首页 > 解决方案 > 在 Vue 中使用 Jest Mock 测试导出的模块

问题描述

我正在尝试对导出的模块进行模拟,但我不知道如何。以下是我的代码。

api

// @/src/api/index.js

...
export const foo = {
  fetch() {
    return Promise.resolve()
  }
}

Vue

import { foo } from '@/api' 

...
data() {
  return {
    receivedData: ''
  }
},
methods: {
  onClickButton() {
    // event listener
    foo.then(data => { this.receivedData = data }
  }
}

test.spec.js

import { shallowMount } from '@vue/test-utils'
import { foo } from '@/api'
...
jest.mock('../../../src/api/index.js') // it does not mock foo

...
  beforeEach(() => {
    foo.mockClear()
    // error : _api.foo.mockClear is not a function
  })

在此示例中,我如何为使用名称foo而不是默认导出的模块(如.exported default foo

标签: javascriptunit-testingvue.jsjestjs

解决方案


api

// @/src/api/index.js

...
export const foo = {
  fetch() {
    return Promise.resolve()
  }
}

// add following
export default {
  foo
}

test.spec.js

import { shallowMount } from '@vue/test-utils'
import api from '@/api' // get a object which have all api functions
...
jest.mock('../../../src/api/index.js', () => {
  // make it similar with 'export default' of api/index.js
  return {
    foo: {
      fetch: jest.fn(() => {
        return {
          then(callback) {
            // pass dummy data as you want or need
            callback({ data: { success: true } })
          }
        }
      })
    }
  }
})

...
  beforeEach(() => {
    // clear mock of each mocked function
    api.foo.fetch.mockClear()
  })

  it('test api', () => {
    const wrapper = shallowMount(Component)
    wrapper.find('button').trigger('click')

    expect(api.foo.fetch).toHaveBeenCalled() // pass it
  })

  it('test api2', () => {
    expect(api.foo.fetch).toHaveBeenCalled() // do not pass it
  })

通过这种方式,我可以处理模拟函数并检查更改的 ui 元素或 vue 实例的数据。


推荐阅读