#使用Mocks测试

    在现实世界的应用程序中,我们的组件很可能具有外部依赖性。当为组件编写单元测试时,如果我们可以模拟这些外部依赖性,以使我们的测试仅依赖于被测试组件的行为,这将是理想的。

    vue-loader提供了一个特性,它允许你使用inject-loader*.vue组件注入任意依赖项。一般的想法是,不是直接导入组件模块,我们使用inject-loader为该模块创建一个“模块工厂”函数。当这个函数被一个mock对象调用时,它返回一个带有mocks的模块的实例。

    假设我们有一个这样的组件:

    1. <!-- example.vue -->
    2. <template>
    3. <div class="msg">{{ msg }}</div>
    4. </template>
    5. <script>
    6. // 这个依赖需要被mocked
    7. import SomeService from '../service'
    8. export default {
    9. data () {
    10. return {
    11. msg: SomeService.msg
    12. }
    13. }
    14. }
    15. </script>

    下面是如何使用mock导入它:

    注意:inject-loader@3.x目前不稳定。

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

    注意,crazy require string - 我们在这里使用一些内联的webpack加载器请求。 快速解释:

    • !!在开始时意味着“禁止所有加载器从全局配置”;
    • vue?inject!意思是“使用vue加载器,并传递?inject查询。 这告诉vue-loader在依赖注入模式下编译组件。

    返回的“ExampleInjector”是一个工厂函数,可以调用它来创建example.vue模块的实例:

    1. const ExampleWithMocks = ExampleInjector({
    2. // mock it
    3. '../service': {
    4. msg: 'Hello from a mocked service!'
    5. }
    6. })

    最后,我们可以像平常一样测试组件:

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