Enzyme simulate返回0节点:Jest测试React组件报错求助
为什么Enzyme的
contains检测到组件存在,但find却找不到? 哈哈,这个问题我之前也踩过坑!让我给你拆解一下为什么会出现这种矛盾的情况,以及怎么解决它。
核心原因分析
1. wrapper.contains(SelectButton)为什么能通过?
Enzyme的contains方法会递归遍历整个渲染树,它并不严格检查组件的引用,而是通过组件的displayName或者元素类型来判断是否存在匹配的组件。所以哪怕SelectButton嵌套在SelectWrapper里面,只要它被渲染出来了,contains就能检测到。
2. wrapper.find(SelectButton)为什么返回0个节点?
find方法用组件构造函数查找时,会严格匹配组件的引用。这就会出现几种常见的问题:
- 你在测试文件里导入SelectButton的方式(比如默认导出
import SelectButton from './SelectButton'),和SelectWrapper里导入它的方式不一致(比如命名导出import { SelectButton } from './SelectButton'),导致两个引用不是同一个对象,find自然找不到。 - 如果SelectWrapper是一个被React.memo包裹、或者是高阶组件包装的组件,mount后的渲染树里,SelectButton被包裹在中间组件的“壳”里,直接用
find(SelectButton)没法穿透找到它。
解决方案
方案一:统一组件导入方式
检查SelectWrapper文件里导入SelectButton的代码,确保和测试文件的导入方式完全一致。比如测试用的是默认导出,那SelectWrapper里也要写:
import SelectButton from './SelectButton';
方案二:用组件的displayName查找
给SelectButton设置正确的displayName,然后用字符串形式查找:
首先在SelectButton组件里设置displayName:
const SelectButton = () => { // 组件逻辑 }; SelectButton.displayName = 'SelectButton'; export default SelectButton;
然后修改测试代码:
wrapper.find('SelectButton').simulate('click');
方案三:通过中间组件dive查找
既然DropDown→SelectWrapper→SelectButton的层级关系明确,你可以先找到SelectWrapper,再用dive()深入它的内部渲染树,之后就能找到SelectButton了:
// 先导入SelectWrapper import SelectWrapper from './SelectWrapper'; // 测试代码修改如下 wrapper.find(SelectWrapper).dive().find(SelectButton).simulate('click');
方案四:用findWhere精准匹配
如果以上方法都不行,可以用findWhere来手动判断节点类型:
wrapper.findWhere(node => node.type() === SelectButton).simulate('click');
内容的提问来源于stack exchange,提问作者darKnight
相关产品推荐
相关产品推荐

