模拟测试

在实际应用中,我们的组件一般都有有外部的依赖项。当为组件写单测试时,如果我们能模拟这些外部依赖项的话,就会非常理想了。

vue-loader 有个功能,允许你在 *.vue 组件内加入任何依赖项,即使用 inject-loader。一般的做法,并不是直接导入模块,而是使用 inject-loader 创建该模块 "模块工厂" 的方法。当使用模拟对象调用这个方法时候,它会返回一个该模块实例对象。

假如我们有这样一个组件:

<!-- example.vue -->
<template>
  <div class="msg">{{ msg }}</div>
</template>

<script>
// 这个依赖项需要被模拟
import SomeService from '../service'

export default {
  data () {
    return {
      msg: SomeService.msg
    }
  }
}
</script>

如下是用模拟对象导入它:

npm install inject-loader --save-dev
// example.spec.js
const ExampleInjector = require('!!vue?inject!./example.vue')

注意 require 内的字符串,这里我们了使用一些内联 webpack loader requests。做下简单解释:

  • 开头部分的 !! 意思是 "全局配置中禁用所有的加载器"。

  • vue?inject! 意思是 "使用 vue 加载器,并传递 ?inject 查询字符串"。也就是让 vue-loader 在依赖注入模式下来编译组件。

返回的 ExampleInjector 是一个工厂方法,该方法创建 example.vue 模块的实例:

const ExampleWithMocks = ExampleInjector({
  // 模拟动作
  '../service': {
    msg: 'Hello from a mocked service!'
  }
})

最后,我们像往常一样测试组件:

it('should render', () => {
  const vm = new Vue({
    template: '<div><test></test></div>',
    components: {
      'test': ExampleWithMocks
    }
  }).$mount()
  expect(vm.$el.querySelector('.msg').textContent).toBe('Hello from a mocked service!')
})

results matching ""

    No results matching ""