Vue 3单元测试如何模拟computed属性?Vue2迁移适配
Vue 3 Jest测试中模拟Computed属性的兼容方案
Vue 3 的 @vue/test-utils 不再支持 Vue 2 中直接在 shallowMount 选项传入 computed 对象的写法,下面针对选项式API和组合式API组件分别提供兼容模拟方案,无需大量重写原有测试。
选项式API组件的模拟方法
方法1:通过setup选项覆盖
直接在挂载时的setup选项中返回模拟的computed值(或computed对象),Vue会自动覆盖组件原有的computed属性:
import { shallowMount } from '@vue/test-utils'; import { computed } from 'vue'; import FooComponent from './FooComponent.vue'; // 简单模拟(直接返回值,Vue会自动解包) const wrapper = shallowMount(FooComponent, { setup() { return { myComputedProp: false }; } }); // 严格模拟computed(保持响应式,可选) const wrapper = shallowMount(FooComponent, { setup() { return { myComputedProp: computed(() => false) }; } });
方法2:用Jest Spy覆盖getter
如果已经挂载组件,可通过修改computed属性的getter方法实现模拟:
const wrapper = shallowMount(FooComponent); jest.spyOn(wrapper.vm.$options.computed.myComputedProp, 'get').mockReturnValue(false);
组合式API组件的模拟方法
组合式API中,computed是在setup函数内定义并返回的,同样可以通过挂载时的setup选项覆盖:
import { shallowMount } from '@vue/test-utils'; import FooComponent from './FooComponent.vue'; // 直接返回模拟值(自动解包) const wrapper = shallowMount(FooComponent, { setup() { return { myComputedProp: false }; } }); // 如需保持响应式,可返回computed对象 import { computed } from 'vue'; const wrapper = shallowMount(FooComponent, { setup() { return { myComputedProp: computed(() => false) }; } });
通用封装(减少重复代码)
如果有大量测试需要修改,可以封装一个工具函数统一处理两种API的模拟:
/** * 模拟组件的computed属性 * @param {Wrapper} wrapper - 组件挂载实例 * @param {Object} computedObj - 要模拟的computed键值对 */ function mockComputed(wrapper, computedObj) { Object.entries(computedObj).forEach(([key, value]) => { if (wrapper.vm.$options.computed?.[key]) { // 选项式API:覆盖getter jest.spyOn(wrapper.vm.$options.computed[key], 'get').mockReturnValue(value); } else { // 组合式API:直接覆盖实例属性 wrapper.vm[key] = value; } }); } // 使用示例 const wrapper = shallowMount(FooComponent); mockComputed(wrapper, { myComputedProp: false });
内容的提问来源于stack exchange,提问作者eXception
相关产品推荐
相关产品推荐

