如何在 JEST 测试中模拟全局 Vue.js 变量

How to mock global Vue.js variable in JEST test

我有一个全局 property/variable 和我的应用程序网址:

Vue.prototype.$apiUrls = {
  root: 'http://localhost:8080/',
  api: 'api/v1/'
  // etc.  
}

我在我的组件中使用它作为 axios 请求:

axios.get(`${this.$apiUrls.root}${this.$apiUrls.api}/users/`)

现在我想测试我的组件代码,我已经模拟了 axios,但我仍然收到错误:

TypeError: Cannot read property '$apiUrls' of undefined

我已经尝试 define/mock 这个 属性 在 JEST 的设置文件中的每个测试 and/or 中,例如

global.$apiUrls = {...}
// or
Vue.prototype.$apiUrls = {...}
// or
Object.defineProperties(Vue.prototype, {$apiUrls: {...}})

我也试过将其模拟为 windowthis(是的,这很愚蠢),但没有成功 - 我仍然收到该错误 - 请帮忙。

您可以在 vue-test-utils beta 15 及更高版本中执行此操作。

这里docs

一些例子是:

import VueTestUtils from '@vue/test-utils'

VueTestUtils.config.mocks['$apiUrls'] = {
  ...
}

有两种方法可以实现。一种是使用 Config 选项,如@Aldarund 所述。你可以阅读它 here.

如果您使用的是 Jest,我建议在 jest.init.js 文件中这样做:

import { config } from '@vue/test-utils'

config.mocks['$apiUrls'] = {
  'some/endpoint'
}

然后将其添加到 package.jsonjest 部分:

"setupFiles": [
  "<rootDir>/jest.init.js"
]

现在它在全球范围内被嘲笑。如果你想在每次测试的基础上这样做,你可以使用 mocks 安装选项:

const wrapper = shallowMount(Foo, {
  mocks: {
    $apiUrls: 'some/endpoint'
  }
})

希望这对您有所帮助!

如果您有兴趣,我正在编写一组关于如何测试 Vue 组件的简单指南 here。它正在开发中,但如果您在测试 Vue 组件方面需要其他相关帮助,请随时提出问题。

我认为上述答案不再适用(2020 年)。

以下是对我有用的方法:

对于 vue-test-utils 1.x.x (Vue 2)

  1. 创建一个新文件,将其命名为例如。 jest.init.js
  2. 给它以下内容:
import { config } from "@vue/test-utils";
config.mocks["yourGlobalProperty"] = label => label; //you can replace it with your own mock
  1. 将此添加到您的jest.config.js(实际上写“rootDir”,不要用真实路径替换任何内容)
module.exports = {
  setupFiles: ["<rootDir>/jest.init.js"]
}

这些文件只会 运行 在 jest 运行单元测试之前。

请注意,我正在导入 {config},而不是默认导出。我不知道为什么默认设置对我不起作用。 Even the documentation for vue test utils doesn't import the default export anymore

还要确保您没有尝试从旧的 vue-test-utils 包中导入。 (新的是@vue/test-utils

对于@vue/test-utils 2.x.x (vue-test-utils-next) (Vue 3)

按照上述 1.x.x 的步骤进行操作,但在第二步中,改为执行此操作:

import { config } from "@vue/test-utils"; //2.0.0-beta.5
config.global.mocks = {
  yourGlobalProperty: label => label
};