Experimenting with Vuejs by testing a function that delivers a Promise upon the execution of the "Created" hook

In my Vuejs application, I have the following script written in Typescript:

import { Foo, FooRepository } from "./foo";
import Vue from 'vue';
import Component from 'vue-class-component';
import { Promise } from "bluebird";

@Component
export default class MyComponent extends Vue {
    isLoading: boolean;
    fooData: Foo;

    data() {
        return {
            isLoading: true,
            fooData: new Foo()
        }
    }

    created() {
        this.populate();
    }

    populate() {
        console.log("populate");
        new FooRepository().get().then((data: Foo) => {
            console.log(data);
            this.isLoading = false;
            this.fooData = data;
        });
    }

The populate method is executed on the created hook. The repository.get() function returns a Promise, and internally it performs a fetch.

To conduct tests, I am attempting to use the following setup:

import * as fetch from "fetch-mock"
import Vue from "vue";
import { mount } from 'vue-test-utils';
import MyComponent from "./component.vue";

describe("Foo", () => {
    afterEach(() => {
        fetch.restore();
    });

    it("retrieves data", (done) => {
        var comp = mount(MyComponent);
        const response = { Title: "Hello, world" };
        fetch.get("/api/called/from/repo", response);

        Vue.nextTick(() => {
            expect(comp.html()).toContain("Hello, world");
            done();
        });
    });
}); 

When running this test, I encounter the following error:

Expected undefined to contain 'Hello, world'.
                 at eval (webpack-internal:///137:16:37)
                 at Array.eval (webpack-internal:///104:1790:12)
                 at flushCallbacks (webpack-internal:///104:1711:14)
                 at <anonymous>

An interesting observation is that changing the implementation of the populate() method to directly return a promise resolves the issue.

Answer №1

If you want to test your component by wrapping it and overriding the created function, follow these steps:

Within your component, make sure to include the promise return in both the created and populate methods:


    created() {
        return this.populate();
    }

    populate() {
        return new BarRepository().fetchData().then((data: Bar) => {
            this.isLoading = false;
            this.barData = data;
        });
    }

In your testing code:


    it("fetches data", (done) => {
        let result;

        const TestComponent = Object.assign({}, MyComponent, {
            created() {
                const res = MyComponent.created.call(this);
                result = res;
                return res;
            },
        });

        const component = mount(TestComponent);

        const responseData = { Message: "Hello, there!" };
        fetch.get("/api/endpoint", responseData);

        result.then(() => {
            Vue.nextTick(() => {
                expect(component.html()).toContain("Hello, there!");
                done();
            });
        });
    });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Mastering the usage of AngularJS Directive controllerAs syntax with scope is key to developing

I have included my code below: // HTML <body> <h1>{{foo.name}}</h1> <my-directive></my-directive> </body> // Scripts app.directive('myDirective', function() { return { restrict: 'E', ...

Unable to save or create files in Store.js

Recently, I've been trying to save a file on client storage using Store.js. After changing the date with store.set and logging it to the console successfully, I encountered an issue where the data was not being saved in the app directory as expected. ...

Retrieve four distinct values using only a single text box input and display them individually on separate lines

Is there a way to receive four input values from the user using just one textbox and display them on separate lines? function collectData() { var userInput, i; var textOutput = " "; for (i = 0; i <= 3; i++) { userInput = document.g ...

The magic of data binding in AngularJS's ng-repeat

Is it possible to dynamically call an attribute of a data-binded object based on the ng-repeat object? I have set up a simple example, but I'm not sure if it can be solved this way. Can anyone help with this? The goal is for the input to receive the ...

How to retrieve a grandchild's property in VUE.js

When working with Vue, I am trying to figure out how to access the 'someProperty' of componentC. This component is a child of componentB, which in turn is a child of componentA, all within the same grandfather componentA. I have attempted the fo ...

Unknown error occurred in Eventstore: Unable to identify the BadRequest issue

I'm encountering an error while using Eventstore, specifically: Could not recognize BadRequest; The error message is originating from: game process tick failed UnknownError: Could not recognize BadRequest at unpackToCommandError (\node_modul ...

What is the best way to toggle a d3 svg overlay using a leaflet layer control?

I am looking for a solution to place 3 d3 svgs on a leaflet map and control them as easily as leaflet layers. Check out this code example, which works but is not ideal. The key part is from line 75 onwards, where I create a custom layer control linked to ...

What is the best way to include the ID when making edits in Angular?

Is there a way to pass the ID when a user edits a document? Below is the HTML and component.ts code: HTML <h1 mat-dialog-title>Hi {{data.name}}</h1> <form [formGroup]="addTaskForm" (ngSubmit)="save()" > <mat-form-field> <ma ...

A step-by-step guide on ensuring mandatory completion of all input fields prior to form submission

I'm new to JavaScript and I need some help. Currently, I am trying to implement input field validation using pure JavaScript for a form. However, I am facing an issue where the "Required" message only appears next to the last name input. What I want ...

How come executing a function in the Node.js REPL using )( actually functions?

In JavaScript, why is it possible to call a function like this when tested with node.js: ~$ node > function hi() { console.log("Hello, World!"); }; undefined > hi [Function: hi] > hi() Hello, World! undefined > hi)( // Why does this work? Hell ...

Detecting typescript syntax errors: checking for if statements and calling class methods

When I'm debugging, I've noticed that the silly mistakes I make are often the hardest to spot. For example: if (id = userId) {..} And in class methods: let result = myClass.doThis; Oddly enough, VSCode doesn't catch these errors during co ...

Navigating Between Pages with Parameters in Ionic 2 (starter app)

I have an Ionic 2 project with a blank template containing a page that displays a list. Upon clicking on an item in the list, the user should be able to view more details about that specific item. Below are the files related to the list: list.html: <i ...

Guide to: Implementing Radio Buttons to Adjust Image Opacity

How can I dynamically change the opacity of an image using JavaScript when a radio button is clicked? I attempted to achieve this using a forEach function, but the current code causes all images to instantly switch to opacity 1; Additionally, after refre ...

Exploring the functionalities of AngularJS' ng-options when working with select elements

In my search through other posts, I came across this issue but couldn't find a solution. Here is the array in question: $scope.items = [ {ID: '000001', Title: 'Chicago'}, {ID: '000002', Title: 'New York' ...

Tips for sorting through existing data without resorting to a remote call - Material Table repository by mbrn (mbrn/material

Currently I am using the mbrn/material-table library which includes filtering on a column and remote data feature. However, when I apply a filter term, the table sends an API call to the server with the filter criteria in the query object. My desired outco ...

How to selectively filter an array of objects using another array in JavaScript

Imagine you have an array filled with objects: people = [ {id: "1", name: "abc", gender: "m", age:"15" }, {id: "2", name: "a", gender: "m", age:"25" }, {id: "3 ...

What is the best way to determine the size of the URLs for images stored in an array using JavaScript?

I am working on a project where I need to surround an image with a specific sized 'div' based on the image's dimensions. The images that will be used are stored in an array and I need to extract the height and width of each image before disp ...

When utilizing ng2-bootstrap, there is no directive that is defined with the "exportAs" attribute set to "bs-modal"

I found a tutorial that I am trying to emulate from this website However, when I insert the template into my HTML file <div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}" tabindex="-1" role="dialog" ...

React - what propType should be used for the Material UI icon?

I am planning to send a Material-UI icon to the Test component and I need to define the correct proptype for it. App.js import "./styles.css"; import VisibilityIcon from "@material-ui/icons/Visibility"; import Test from "./Test&q ...

Tips for stopping slide transition (moving to a different slide) in vue-slick-carousel?

I'm utilizing vue-slick-carousel to populate schedule data for a specific slide (in this case, a month). <vue-slick-carousel @afterChange="afterChange" @beforeChange="beforeChange" @swipe="swipe" class="te ...