Vue中如何使用vue-test-utils与Jest测试v-show控制的子组件可见性
Vue Test Utils + Jest 测试 v-show 控制的子组件可见性指南
报错根源说明
遇到的
wrapper.findComponent(...).hasStyle is not a function报错,核心原因是:findComponent返回的是组件实例包装器(VueWrapper),而hasStyle是仅针对原生DOM元素的DOMWrapper的专属方法,二者API不互通,旧版示例的写法已不适配当前版本的测试工具。
v-show 的本质特性
v-show 不会让子组件脱离渲染树,仅通过给元素添加内联样式display: none控制显隐,因此测试时不能使用exists()判断(不管显隐子组件都是存在的),需要校验DOM的真实样式表现。
与v-if测试的差异
- v-if 属于条件渲染:不满足条件时子组件完全不会挂载,直接用
findComponent(ChildComponent).exists()断言即可。 - v-show 属于样式控制:子组件始终挂载,需要断言其根节点的
display内联样式。
正确测试实现方案
方案1:直接校验DOM原生样式(最简洁,推荐)
VueWrapper自带element属性,可直接访问子组件根节点的原生DOM对象,读取其内联样式即可判断显隐:
// 挂载父组件后,找到目标子组件 const childWrapper = wrapper.findComponent(ChildComponent) // 断言可见状态:无display: none样式 expect(childWrapper.element.style.display).not.toBe('none') // 断言隐藏状态:存在display: none样式 expect(childWrapper.element.style.display).toBe('none')
方案2:使用DOMWrapper调用内置方法(语义更清晰)
如果更习惯使用测试工具的封装方法,可以将子组件的根DOM节点手动转为DOMWrapper后再调用hasStyle:
import { DOMWrapper } from '@vue/test-utils' import ChildComponent from './ChildComponent.vue' const childWrapper = wrapper.findComponent(ChildComponent) // 把子组件的根DOM节点包装为DOMWrapper const childDom = new DOMWrapper(childWrapper.element) // 断言样式 expect(childDom.hasStyle('display', 'none')).toBe(true) // 隐藏 expect(childDom.hasStyle('display', 'none')).toBe(false) // 可见
完整测试用例参考
import { mount } from '@vue/test-utils' import ParentComponent from './ParentComponent.vue' import ChildComponent from './ChildComponent.vue' describe('v-show控制的子组件显隐测试', () => { it('初始isShowing为true时,子组件可见', () => { const wrapper = mount(ParentComponent) const child = wrapper.findComponent(ChildComponent) expect(child.element.style.display).not.toBe('none') }) it('修改isShowing为false后,子组件隐藏', async () => { const wrapper = mount(ParentComponent) // 修改响应式状态后等待DOM异步更新 await wrapper.setData({ isShowing: false }) const child = wrapper.findComponent(ChildComponent) expect(child.element.style.display).toBe('none') }) })
注意事项
- 不要仅通过断言
wrapper.vm.isShowing的取值判断显隐:这种方式仅校验控制变量是否符合预期,无法覆盖「v-show绑定错误、样式被覆盖」等实际渲染异常,属于逻辑分支测试而非视图渲染测试。 - 若子组件是多根节点(无唯一根元素的Fragment模板),
element属性会返回第一个根节点,需结合组件实际结构,通过选择器精确定位被v-show绑定的DOM元素后再校验。
内容的提问来源于stack exchange,提问作者Clarity
相关产品推荐
相关产品推荐

