【问题标题】:Vuejs test a function that returns a Promise on "Created" hookVuejs 测试一个在“Created”钩子上返回 Promise 的函数
【发布时间】:2018-05-05 02:49:43
【问题描述】:

我有一个带有以下脚本(在 Typescript 中)的 Vuejs 应用程序:

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;
        });
    }

所以在created钩子上调用populate方法,repository.get()返回一个Promise,实现是在执行一个fetch

为了测试这一点,我正在尝试使用:

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();
        });
    });
}); 

我遇到的问题是在运行这个测试时我得到:

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>

奇怪的是,如果我将 populate() 的实现更改为直接返回一个承诺的东西,那么这工作正常。

【问题讨论】:

  • 尝试mounted 而不是createdcreated 的问题是该组件甚至可能无法呈现,甚至可能无法使用其数据属性或方法。 mounted 完全避免这个问题,只在一切准备就绪后执行。

标签: javascript typescript vue.js vuejs2 karma-jasmine


【解决方案1】:

您可以在测试时包装您的组件并覆盖创建的函数。

在您的组件中,您需要在createdpopulate 中返回承诺:

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

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

在你的测试中:

    it("retrieves data", (done) => {
        let createdResult;

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

        const comp = mount(MyComponentText);

        const response = { Title: "Hello, world" };
        fetch.get("/api/called/from/repo", response);

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

【讨论】:

    猜你喜欢
    • 2019-07-18
    • 2017-03-26
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    • 2018-01-20
    • 2020-03-25
    • 2020-06-20
    • 2020-06-19
    相关资源
    最近更新 更多