使用Jest测试Vue3组合式函数时遭遇循环结构转JSON错误
解决Jest测试Vue3 useClassNames组合式函数的两个问题:循环引用警告与断言失败
问题分析
1. 循环结构转JSON警告
当运行包含useClassNames的组件测试时,Jest尝试序列化组件内部的ComputedRef对象,而该对象内部存在循环引用(ComputedRefImpl的effect属性指向自身),导致抛出TypeError: Converting circular structure to JSON警告。
2. 断言失败
useClassNames返回的是Vue的ComputedRef响应式对象,而非直接的数组。测试代码中直接用toBe([])比较对象与数组,因严格引用不相等导致断言失败。
解决方案
1. 修复断言失败问题
修改测试代码,通过.value访问计算属性的实际值,并使用toEqual(而非toBe)比较数组:
import useClassNames from './useClassNames'; describe('useClassNames', () => { it('返回空数组当传入空选项时', () => { const result = useClassNames([]); expect(result.value).toEqual([]); }); // 可补充更多测试用例覆盖场景 it('返回基础类名当选项包含base时', () => { const result = useClassNames([{ base: 'test' }]); expect(result.value).toEqual(['test']); }); it('返回带修饰符的类名当提供modifier时', () => { const result = useClassNames([{ base: 'test', modifier: 'active' }]); expect(result.value).toEqual(['test--active']); }); it('当condition为false时忽略该选项', () => { const result = useClassNames([{ base: 'test', condition: false }]); expect(result.value).toEqual([]); }); it('添加额外传入的类名', () => { const result = useClassNames([], 'extra-class'); expect(result.value).toEqual(['extra-class']); }); });
2. 解决循环引用警告
组件测试应关注最终UI输出,而非内部响应式对象。通过断言渲染后的DOM元素类名,避免直接处理ComputedRef:
以Button组件测试为例:
import { mount } from '@vue/test-utils'; import Button from './Button.vue'; describe('Button', () => { it('渲染默认button类名', () => { const wrapper = mount(Button); expect(wrapper.find('button').classes()).toContain('button'); }); it('当设置variant属性时渲染对应修饰符类名', () => { const wrapper = mount(Button, { props: { variant: 'primary' } }); expect(wrapper.find('button').classes()).toContain('button--primary'); }); it('添加来自addClassNames属性的额外类名', () => { const wrapper = mount(Button, { props: { addClassNames: 'custom-class' } }); expect(wrapper.find('button').classes()).toContain('custom-class'); }); });
内容的提问来源于stack exchange,提问作者Bong2000
相关产品推荐
相关产品推荐

