如何在Jest中Mock Vue组件里嵌套的this层级函数?
解决独立Vue组件Jest Mock $parent嵌套属性的问题
你之前的方法失效主要是两个原因:一是直接修改wrapper.vm.$parent的时机太晚(mounted钩子已经执行);二是没有构建完整的嵌套属性层级,导致spyOn或赋值找不到对应的对象。下面是三种可行的解决方案:
方案一:挂载时通过mocks选项构建完整嵌套结构
在挂载组件时,直接通过mocks参数从$parent开始逐层构建mock对象,确保组件mounted时能访问到完整的方法:
import { shallowMount } from '@vue/test-utils' import TargetComponent from './TargetComponent.vue' describe('TargetComponent', () => { it('calls $getSomeData when mounted', () => { // 定义mock函数 const mockGetData = jest.fn().mockReturnValue('mocked content') // 挂载时传入完整的嵌套mock const wrapper = shallowMount(TargetComponent, { mocks: { $parent: { $someValue: { $getSomeData: mockGetData } } } }) // 验证函数被调用 expect(mockGetData).toHaveBeenCalled() }) })
方案二:测试前全局mock Vue原型的$parent属性
如果需要在多个测试用例中复用这个mock,可以在测试前给Vue原型的$parent赋值,测试后清理避免污染:
import Vue from 'vue' import { mount } from '@vue/test-utils' import TargetComponent from './TargetComponent.vue' describe('TargetComponent', () => { let mockGetData beforeEach(() => { mockGetData = jest.fn().mockReturnValue('mocked content') // 全局mock嵌套结构 Vue.prototype.$parent = { $someValue: { $getSomeData: mockGetData } } }) afterEach(() => { // 清理mock jest.restoreAllMocks() delete Vue.prototype.$parent }) it('triggers data fetch on mounted', () => { const wrapper = mount(TargetComponent) expect(mockGetData).toHaveBeenCalled() }) })
方案三:通过beforeMount钩子提前注入mock
利用测试工具的beforeMount钩子,在组件mounted执行前手动注入$parent的嵌套结构:
import { shallowMount } from '@vue/test-utils' import TargetComponent from './TargetComponent.vue' describe('TargetComponent', () => { it('executes $getSomeData on mount', () => { const mockGetData = jest.fn().mockReturnValue('mocked content') const wrapper = shallowMount(TargetComponent, { beforeMount() { // 在mounted前给当前实例赋值$parent this.$parent = { $someValue: { $getSomeData: mockGetData } } } }) expect(mockGetData).toHaveBeenCalled() }) })
内容的提问来源于stack exchange,提问作者JSlip
相关产品推荐
相关产品推荐

