如何使用' @ vue / test-utils'?

时间:2018-05-30 21:29:18

标签: unit-testing vue.js vue-router vuex vue-test-utils

我试图测试我的容器'处理表单逻辑的组件。它使用vue-routervuex商店来分派操作以获取表单详细信息。

我有以下单位代码,但没有按预期运作:

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很新,所以如果我错过了一些非常明显的东西,请向你道歉,并提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

查看此文档: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
});