Vue3 Testing Library测试中如何注入或模拟globalProperties全局属性
解决方案
问题原因
测试环境不会自动加载项目main.js中注册的全局配置,你挂载到app.config.globalProperties上的$globals等全局属性,默认在测试渲染的组件实例中不存在,所以调用this.$globals会返回undefined,触发属性读取报错。
修复方式
你可以通过Vue Testing Library的render函数第二个参数的global配置项,注入全局属性、组件、插件:
临时修复当前测试用例
直接修改你的test.spec.js的initSettings配置,新增global.mocks字段模拟全局属性:
import { render } from '@testing-library/vue' import FormatedNumericInput from '@/components/Component.vue' import {globalMethods} from'@/config/global-methods' // 如果用到全局注册的font-awesome-icon也可以导入对应模拟/实际依赖 // import fontawesome from '@/plugins/fontawesome' const label = 'Price' const initSettings = { props: { inputId: 'testInputId1', labelTxt: label }, // 新增全局配置 global: { // 模拟全局属性 mocks: { $globals: globalMethods, $globalVars: {} // 按需填入测试需要的全局变量 }, // 如果组件用到全局注册的font-awesome-icon,在这里注册 // components: { // 'font-awesome-icon': fontawesome // }, // 如果测试需要用到vuex/pinia、i18n等插件,也可以在这里引入 // plugins: [i18n, applicationStore] } }; test('a simple string that defines your test', () => { const { getByLabelText } = render(FormatedNumericInput, initSettings) const input = getByLabelText(label) // testing logic expect(input).not.toBeNull() expect(FormatedNumericInput).not.toBeNull() })
多测试用例复用全局配置
如果你的大部分测试都需要用到这些全局配置,可以封装自定义render函数,避免重复编写配置:
- 新建测试工具文件
tests/utils/render.js
import { render as originalRender } from '@testing-library/vue' import { globalMethods } from '@/config/global-methods' import fontawesome from '@/plugins/fontawesome' import i18n from '@/i18n' import applicationStore from '@/store' // 预设默认全局配置 const defaultGlobalConfig = { mocks: { $globals: globalMethods, $globalVars: {} }, components: { 'font-awesome-icon': fontawesome }, plugins: [i18n, applicationStore] } export function render(component, options = {}) { // 合并用户传入的配置和默认配置 const finalGlobal = { ...defaultGlobalConfig, ...options.global } return originalRender(component, { ...options, global: finalGlobal }) }
- 后续测试直接导入自定义的render函数即可:
import { render } from 'tests/utils/render' import FormatedNumericInput from '@/components/Component.vue' const label = 'Price' const initSettings = { props: { inputId: 'testInputId1', labelTxt: label } }; test('a simple string that defines your test', () => { const { getByLabelText } = render(FormatedNumericInput, initSettings) // 测试逻辑 })
内容的提问来源于stack exchange,提问作者devtime
相关产品推荐
相关产品推荐

