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

Posted

技术标签:

【中文标题】如何在 JEST 测试中模拟全局 Vue.js 变量【英文标题】:How to mock global Vue.js variable in JEST test 【发布时间】:2018-12-15 07:30:26 【问题描述】:

我的应用网址有一个全局属性/变量:

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

我尝试在每个测试和/或 JEST 的设置文件中定义/模拟此属性,例如

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

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

【问题讨论】:

你也在用vue-test-utils吗? @Derek 不在此特定项目中,但如有必要,我也愿意在这里开始使用它;) 我担心的是文档的一部分是这样说的:Note some plugins, like Vue Router, add read-only properties to the global Vue constructor. This makes it impossible to reinstall the plugin on a localVue constructor, or add mocks for these read-only properties hmn 但我认为如果我想模拟 $router 道具,或者如果我使用类似 Vue.use(myPluginWithApiUrlProperty) 的东西(但不确定) 你解决了吗?如果您需要任何澄清,请告诉我! 【参考方案1】:

我认为上述答案不再有效(2020 年)。

这对我有用:

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

    创建一个新文件,命名为例如。 jest.init.js 给它以下内容:
import  config  from "@vue/test-utils";
config.mocks["yourGlobalProperty"] = label => label; //you can replace it with your own mock
    将此添加到您的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
;

【讨论】:

【参考方案2】:

有两种方法可以实现这一点。一种是使用@Aldarund 提到的Config 选项。你可以阅读它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 组件,请随时提出问题。

【讨论】:

这不再有效。你需要做import config from "@vue/test-utils"。见vue-test-utils.vuejs.org/api/#config @xenetics 你应该已经承认了 Artur 的评论或回答,因为你刚刚根据他的更新。【参考方案3】:

您可以使用 vue-test-utils beta 15 及更高版本进行操作。

这里docs

还有一些例子:

import VueTestUtils from '@vue/test-utils'

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

【讨论】:

以上是关于如何在 JEST 测试中模拟全局 Vue.js 变量的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jest 测试 Vue.js 组件中方法的错误

如何测试我的数据是不是更改? (Vue JS、Jest、单元测试)

在 Jest 中模拟全局变量

使用 Jest 在 Nuxt 中测试组件时如何添加/模拟 Nuxt Auth 库

用 Jest 和 Typescript 模拟一个全局对象

Jest - 测试在反应变量中声明的 Vue.js 函数