如何在$route上对VueJS watcher进行单元测试?

问题描述 投票:3回答:3

我正在测试一个使用vue router来监视$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 });
});

我在SFC中的监视方法

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

你如何模拟路由器,让你可以监视它并测试监视方法是否如你所愿?

unit-testing vue.js vuex avoriaz vue-test-utils
3个回答
1
投票

这是我如何测试一个路由变化的手表,将当前的路由名称作为一个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')
  })
})

0
投票

测试方法是: [email protected][email protected].

我检查了如何 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(); 

Source: 源: install.js


-1
投票

其实方法就是使用vue-test-utils包装器方法。setData.

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

© www.soinside.com 2019 - 2024. All rights reserved.