如何使用“@vue/test-utils”测试 VueRouter 的 beforeRouteEnter?
Posted
技术标签:
【中文标题】如何使用“@vue/test-utils”测试 VueRouter 的 beforeRouteEnter?【英文标题】:How to test VueRouter's beforeRouteEnter using '@vue/test-utils'? 【发布时间】:2018-11-09 20:02:33 【问题描述】:我正在尝试测试处理表单逻辑的“容器”组件。它使用vue-router
和vuex
存储来调度操作以获取表单详细信息。
我有以下未按预期工作的单元代码:
it('On route enter, it should dispatch an action to fetch form details', () =>
const getFormDetails = sinon.stub();
const store = new Vuex.Store(
actions: getFormDetails
);
const wrapper = shallowMount(MyComponent, store );
wrapper.vm.$options.beforeRouteEnter[0]();
expect(getFormDetails.called).to.be.true;
);
使用以下组件(删除所有内容,因为我认为它不相关(希望如此):
export default
async beforeRouteEnter(to, from, next)
await store.dispatch('getFormDetails');
next();
;
我收到以下断言错误:
AssertionError: expected false to be true
我猜这是因为我没有在测试中安装路由器和localVue。我尝试按照这些步骤操作,但似乎无法调用beforeRouteEnter
。
理想情况下,我希望为路由器注入一个起始路径,并对路由更改进行不同的测试。对于我的用例,我想根据路由器的路径注入不同的道具/调度不同的动作。
我是 Vue 的新手,如果我遗漏了一些非常明显的东西,我深表歉意,并提前感谢您的帮助! ??????
【问题讨论】:
【参考方案1】:查看此文档:https://lmiller1990.github.io/vue-testing-handbook/vue-router.html#component-guards
根据文档,您的测试应如下所示:
it('On route enter, it should dispatch an action to fetch form details', async () =>
const getFormDetails = sinon.stub();
const store = new Vuex.Store(
actions: getFormDetails
);
const wrapper = shallowMount(MyComponent, store );
const next = sinon.stub()
MyComponent.beforeRouteEnter.call(wrapper.vm, undefined, undefined, next)
await wrapper.vm.$nextTick()
expect(getFormDetails.called).to.be.true;
expect(next.called).to.be.true
);
【讨论】:
【参考方案2】:beforeRouteEnter
的一个常见模式是直接在实例化的vm
实例上调用方法。 The documentation states:
beforeRouteEnter 守卫无权访问这个,因为守卫在导航确认之前被调用,因此新的进入组件甚至还没有创建。
但是,您可以通过将回调传递给 next 来访问该实例。导航确认后会调用回调,并将组件实例作为参数传递给回调:
beforeRouteEnter (to, from, next) next(vm => // access to component instance via `vm` )
这就是为什么在这种情况下简单地创建 next
的存根或模拟回调不起作用的原因。我通过为next
使用以下参数解决了这个问题:
// mount the component
const wrapper = mount(Component, );
// call the navigation guard manually
Component.beforeRouteEnter.call(wrapper.vm, undefined, undefined, (c) => c(wrapper.vm));
// await
await wrapper.vm.$nextTick();
【讨论】:
(c) => c(wrapper.vm)
是我需要的。谢谢。以上是关于如何使用“@vue/test-utils”测试 VueRouter 的 beforeRouteEnter?的主要内容,如果未能解决你的问题,请参考以下文章
@vue/test-utils 未知的自定义元素:<router-view>
如何使用 vue-test-utils 在单元测试期间触发窗口事件
VueJs 如何删除全局错误处理程序以使用 vue-test-utils 进行测试
@vue/test-utils 中的 mount() 和 shallowMount() 抛出 TypeError: Cannot read property 'components' of undef