使用 `vue-test-utils` 和 `jest` 使用 `Created` 钩子进行测试
Posted
技术标签:
【中文标题】使用 `vue-test-utils` 和 `jest` 使用 `Created` 钩子进行测试【英文标题】:Testing with `Created` hook with `vue-test-utils` and `jest` 【发布时间】: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();
);
);
我可以做这个创建的钩子的单元测试用例吗?
【问题讨论】:
【参考方案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
属性中。每个钩子都有一个选项,它是一组函数。需要注意的是,上下文并不绑定到所述函数,因此您需要使用call
或apply
来执行它们。
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)
【讨论】:
以上是关于使用 `vue-test-utils` 和 `jest` 使用 `Created` 钩子进行测试的主要内容,如果未能解决你的问题,请参考以下文章
使用 element-ui 和 vue-test-utils 模拟选择
如何在单元测试期间使用 vue-test-utils 和 jest 模拟 mixin?
vue-test-utils:在同一个测试中模拟 vue-router 和 vuex