6

我正在测试一个使用 vue 路由器观看 $route 的单文件组件。问题是我无法让测试既改变路线又触发观察者的功能。

测试文件:

import { createLocalVue, shallow } from 'vue-test-utils';

import Vue from 'vue';
import Vuex from 'vuex';
const localVue = createLocalVue();
localVue.use(Vuex);

const $route = {
  path: '/my/path',
  query: { uuid: 'abc' },
}

wrapper = shallow({
  localVue,
  store,
  mocks: {
   $route,
  }
});

it('should call action when route changes', () => {
    // ensure jest has a clean state for this mocked func
    expect(actions['myVuexAction']).not.toHaveBeenCalled();
    vm.$set($route.query, 'uuid', 'def');
    //vm.$router.replace(/my/path?uuid=def') // tried when installing actual router
    //vm.$route.query.uuid = 'def'; // tried
    //vm.$route = { query: { uuid: 'def'} }; // tried
    expect(actions['myVuexAction']).toHaveBeenLastCalledWith({ key: true });
});

我在证监会的观察方法:

  watch: {
    $route() {
      this.myVuexAction({ key: true });
    },
  },

您如何模拟路由器以使您可以观看它并测试 watch 方法是否按预期工作?

4

4 回答 4

2

这就是我测试路由更改监视的方式,它将当前路由名称作为 css 类添加到我的应用程序组件中:

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

import MyApp from './MyApp'

describe('MyApp', () => {
  it('adds current route name to css classes on route change', () => {
    // arrange
    const localVue = createLocalVue()
    localVue.use(VueRouter)
    const router = new VueRouter({ routes: [{path: '/my-new-route', name: 'my-new-route'}] })
    const wrapper = shallowMount(MyApp, { localVue, router })

    // act
    router.push({ name: 'my-new-route' })

    // assert
    expect(wrapper.find('.my-app').classes()).toContain('my-new-route')
  })
})
于 2018-07-16T04:49:05.480 回答
1

vue@2.6.11和测试vue-router@3.1.3

我在我的测试中检查了如何VueRouter初始化$route$router复制它。以下工作不VueRouter直接使用:

const localVue = createLocalVue();

// Mock $route
const $routeWrapper = {
    $route: null,
};
localVue.util.defineReactive($routeWrapper, '$route', {
    params: {
        step,
    },
});
Object.defineProperty(localVue.prototype, '$route', {
    get() { return $routeWrapper.$route; },
});

// Mock $router
const $routerPushStub = sinon.stub();
localVue.prototype.$router = { push: $routerPushStub };

const wrapper = shallowMount(TestComponent, {
    localVue,
});

更新$route应该始终通过替换整个对象来完成,这是它在不使用深度观察器的情况下工作的唯一方式, $route也是VueRouter行为方式:

$routeWrapper.$route = { params: { step: 1 } };
await vm.wrapper.$nextTick(); 

来源:install.js

于 2020-05-05T15:58:32.623 回答
0

它为我工作

let $route = {
  name: 'any-route',
};

我们定义了一个 $route 并且我们调用了 like

  wrapper = mount(YourComponent, {
    mocks: {
      $route,
    },
  });

我的组件是这样的

  @Watch('$route', { deep: true, immediate: true, })
  async onRouteChange(val: Route) {
    if (val.name === 'my-route') {
      await this.getDocumentByUrl();
      await this.allDocuments();
    }
   };

pd:我使用打字稿,但这适用于另一种格式

最后是我的测试

it('my test', ()=>{
    const getDocumentByUrl = jest.spyOn(wrapper.vm, 'getDocumentByUrl');
    const allDocuments = jest.spyOn(wrapper.vm, 'allDocuments');
    wrapper.vm.$route.name = 'my-route';
    await flushPromises();
    expect(getDocumentByUrl).toHaveBeenCalled();
    expect(allDocuments).toHaveBeenCalled();
})
于 2021-04-23T01:00:37.877 回答
-1

这样做的方法实际上是使用 vue-test-utils 包装方法,setData.

wrapper.setData({ $route: { query: { uuid: 'def'} } });

于 2017-12-15T17:32:10.573 回答