【问题标题】:Testing with `Created` hook with `vue-test-utils` and `jest`使用 `vue-test-utils` 和 `jest` 使用 `Created` 钩子进行测试
【发布时间】:2019-09-26 22:05:39
【问题描述】:

我有一个这样的 Vue 页面:

<template>
</template>

<script>
created(){
    this.doSomething();
}

methods: {
    doSomething() {
        .....
    }
}

</script>

现在,我们要测试这个创建的钩子并检查是否调用了 doSomething() 方法。

这样试了,在package.json中也导入jest

import {
  shallowMount,
  createLocalVue,
} from '@vue/test-utils';

const localVue = createLocalVue();

import Xyx from '/Xyx.vue';

const init = () => {
  wrapper = shallowMount(Xyx, { localVue });
  cmp = wrapper.vm;
};

describe('#created', () => {
  it('#doSomething', () => {
    init();
    wrapper.setMethods({
      doSomething: jest.fn(),
    })
    expect(cmp.doSomething).toHaveBeenCalled();
  });
});

我可以做这个创建的钩子的单元测试用例吗?

【问题讨论】:

    标签: vue.js jestjs vuex vue-test-utils


    【解决方案1】:

    因为您的方法是在 created 上调用的,所以它在您设置模拟之前运行。因此,您的测试将失败。
    您必须在初始化时用模拟替换该方法(在您的情况下,在 shallowMount 上):

    describe('Xyz', () => {
      it('should call doSomething() when created', () => {
        const doSomething = jest.fn()
        wrapper = shallowMount(Xyz, {
          localvue,
          methods: { doSomething }
        });
        expect(doSomething).toHaveBeenCalled();
      });
    });
    

    旁注:您没有声明cmp。在测试开始时,您应该有一个let cmp;


    一个非常相似的讨论here。在链接的评论上方,有一个方法可以模拟大多数 Vue 组件生命周期钩子的属性。

    【讨论】:

    • 应该是expect(doSomething).toHaveBeenCalled();否则会报错Matcher error: received value must be a mock or spy function
    • @tao,谢谢你的方法。但是,expect(wrapper.vm.doSomething) 对我不起作用,并返回了@WhosDustin 指定的错误。 @WhosDustin,感谢您的更正,我的测试运行成功。
    • @elushnikova,请提出一个新问题并提供相关代码。如果您已经完成了上述操作(模拟了该方法,将其放置在 shallowMount 或 mount 的方法中,并完成了该组件应该执行的任何操作以触发该方法)它应该可以工作。没有看到你的代码,我无能为力。错误 per-se 表明您无法评估该方法是否被调用,因为它没有被模拟(它没有被间谍函数替换,如我的示例所示)。
    • 我也确认了@WhosDustin 提到的错误,他的解决方案有效
    【解决方案2】:

    methods 选项在 @vue/test-utils 的 v1 中已弃用,因此接受的答案不再有效。我自己遇到了这个问题,并决定深入研究源代码以找出如何测试它。

    看起来 Vue 实际上将所有挂钩存储在 $options 属性中。每个钩子都有一个选项,它是一组函数。需要注意的是,上下文并不绑定到所述函数,因此您需要使用callapply 来执行它们。

    vm.$options.created.forEach(hook => {
      hook.call(vm);
    });
    

    【讨论】:

    • 你能举个完整的例子吗?
    【解决方案3】:

    当我们需要在我们的测试中调用钩子是可能的。例如,如果我们需要在调用钩子之前模拟一些数据。

    import App from '@/App.vue';
    
    // in test
    App.created.call(wrapper.vm);
    

    同样在 Typescript 中,如果我们使用 vue-property-decorator 它会改变组件的形状,所以需要这样做:

    App.extendOptions.created.call(wrapper.vm)
    

    【讨论】:

      猜你喜欢
      • 2020-02-13
      • 2019-05-28
      • 2018-08-06
      • 2019-10-24
      • 2019-04-19
      • 2018-09-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-22
      相关资源
      最近更新 更多