【问题标题】:How to test VueRouter's beforeRouteEnter using '@vue/test-utils'?如何使用“@vue/test-utils”测试 VueRouter 的 beforeRouteEnter?
【发布时间】:2018-11-09 20:02:33
【问题描述】:

我正在尝试测试处理表单逻辑的“容器”组件。它使用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 的新手,如果我遗漏了一些非常明显的东西,我深表歉意,并提前感谢您的帮助! ??????

【问题讨论】:

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


    【解决方案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) 是我需要的。谢谢。
      猜你喜欢
      • 2019-10-24
      • 2019-04-17
      • 2018-09-28
      • 2021-04-03
      • 1970-01-01
      • 2019-07-16
      • 2021-09-11
      • 2021-02-17
      • 2019-05-28
      相关资源
      最近更新 更多