Vue Utils Test With Jest

449 阅读2分钟

跟着步骤,一步一步的上手Vue单元测试,基本上覆盖了常用的场景,复杂的场景,参考官方文档吧。

  1. 创建vue app
npm install -g vue-vli
vue init webpack vue-jest

安装过程单元测试方案选择jest

安装完成后jest的配置文件在src/test/unit/jest.conf.js

{  
    rootDir: path.resolve(__dirname, '../../'),  
    moduleFileExtensions: [    
        'js',    
        'json',    
        'vue'  
    ],  
    moduleNameMapper: {   
        '^@/(.*)$': '<rootDir>/src/$1'  
    },  
    transform: {    
        '^.+\\.js$': '<rootDir>/node_modules/babel-jest',    
        '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'  
    },  
    snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],  
    setupFiles: ['<rootDir>/test/unit/setup'],  
    coverageDirectory: '<rootDir>/test/unit/coverage',  
    collectCoverageFrom: [    
        'src/**/*.{js,vue}',    
        '!src/main.js',    
        '!src/router/index.js',    
        '!**/node_modules/**'  
    ],  
    testURL: 'http://localhost/'
}

2. 运行默认测试用例

npm run test

可能会出现报错

解决方案

jest.conf.js中设置testURL

module.exports = {
    ...
    testURL: 'http://localhost/'
}

再次测试

3. 组件测试

增加HelloWorld.spec.js文件

import Vue from 'vue'
import HelloWorld from '@/components/HelloWorld'

describe('HelloWorld.vue', () => {
  it('should render right contents', () => {
    // create a copy of the original component
    const Constructor = vue.extend(HelloWorld) 

    // instances and mounts the component
    const vm = new Constructor().$mount() 

    expect(vm.msg).toEqual('Welcome to Your Vue.js App')
  })
})

运行 npm run test 执行测试

4. 浅渲染测试

浅渲染测试是指渲染一个组件自身而不渲染其子组件,这样既符合单元测试的意义,又避免子组件的一些副作用(HTTP请求,获取store数据)

Vue要实现浅渲染,需要确保安装以下依赖jest、babal-jest、vue-test-utils,如果没有安装则增加相关依赖

yarn add -D @vue/test-utils jest babel-jest

增加App.spec.js文件

import { shallowMount } from '@/vue/test-utils'
import App from '../../../src/App'

decsribe('App.spec.js', () => {
  let wrapper
  beforeEach(() => {
     wrapper = shallowMount(App /*{}*/)
  })
  it('should has html structure', () => {
    expect(wrapper.element).toMatchSnapshot()
  })
})

运行 npm run test 执行测试,测试的快照文件中并没有渲染_App_的子组件

5. 断言emited 事件

每个mount的wrapper都记录emited的事件,可以通过wrapper.emited()获取事件

it('get emited event', () => {
  const wrapper = mount(Conponent)
  wrapper.vm.$emit('foo', 123)
  expect(wrapper.emited().foo.length).toBe(1)
  expect(wrapper.emited().foo[0]).toEqual([123])
})

6. 修改组件的state

wrapper.setData({count: 10})
wrapper.setProps({name: 'jay'})

7. 使用全局的plugins和mixins

import { createLocalVue, mount } from '@/vue/test-utils'

// create a copy of Vue
const localVue = createLocalVue()

// install plugins as normal
localVue.use(MyPlugin)

// pass the localVue to the mount options
mount(Component, {
  localVue
})

8. mock 注入

对于全局的注入(store、route)可以使用mock

const $route = {path: 'http://www.example-path.com'}
const wrapper = shallowMount(Component, {
  mocks: {
    $route
  }
})
expect(wrapper.vm.$route.path).toBe($route.path)

9. 编写测试用例的原则

对于UI 组件的测试不要求覆盖到每一行,一方面这样需要考虑的情况比较多,另一方面也会大大增加测试的时间。应该多关注公共的接口方法,只关心输入和输出。

10. 参考链接

The Document of Vue Test Utils

The Document of Jest