Jest+Enzyme测试onClick切换class未检测到wrapper更新问题
问题原因
- 你的
unHideUl方法是直接通过原生DOM API修改元素类名,没有触发React的重渲染流程,Enzyme的wrapper默认会缓存已渲染的节点快照,不会自动同步原生DOM的变更,所以你从wrapper读取的类名还是旧的缓存结果。 - 你选择元素的层级逻辑不稳定,很容易出现查找目标错误的问题,如果你点击的li内部存在子元素,Enzyme模拟点击时传入的事件对象
target可能指向li内部的子元素,导致nextSibling找不到你要操作的ul元素。 - 部分版本的Enzyme模拟事件时不会完整模拟浏览器的事件行为,也可能导致DOM操作逻辑和实际运行效果不一致。
解决思路
- 优先修改组件实现逻辑,把树形节点的展开状态存在React state中,通过state控制类名的增减,符合React的声明式开发规范,测试时也不会出现DOM同步的问题。
- 如果你不想修改现有组件逻辑,可以在模拟点击后手动调用
wrapper.update()方法,强制Enzyme同步最新的DOM状态,再做断言。 - 也可以直接获取原生DOM节点做断言,原生DOM的属性是实时更新的,不存在缓存问题,不用依赖Enzyme的状态同步。
- 给目标节点添加
data-testid属性来选择元素,避免层级查找出现的目标错误问题。
修正后的测试代码示例
let wrapper beforeEach(() => { wrapper = mount(<MyComponent/>) }); afterEach(() => { wrapper.unmount(); }) test('Expect to be expanded', () => { const item = wrapper.find('li').first() item.simulate('click') // 强制同步DOM状态 wrapper.update() const uList = wrapper.find('ul').first().children().find('ul').first() // 直接读取原生DOM的类名做判断 expect(uList.getDOMNode().classList.contains('myHiddenClass')).toBeFalsy() })
内容的提问来源于stack exchange,提问作者Jeppe Christensen
相关产品推荐
相关产品推荐

