Enzyme与TypeScript测试Render Props组件时出现无名节点问题
问题分析与解决方案
首先咱们来拆解你遇到的两个核心问题:无名节点的由来和测试失败的根源,再一步步解决。
为什么会出现无名节点?
你看到的<n>、<i>这类占位符,是Enzyme没法识别组件真实名称时的默认输出。主要原因有两个:
- 第三方组件(
ProgressBar/Step)可能没设置displayName属性,或者导出方式导致Enzyme获取不到可读的组件名; - TypeScript编译过程中,可能会改变组件的名称标识,导致你用字符串(比如
'ProgressBar')查找时,Enzyme匹配不到对应的组件类型。
测试失败的核心原因
- 你用
mountedComponent.find('ProgressBar Step')这种嵌套字符串查找,本质是依赖组件的名称匹配,但Enzyme识别不了组件名,自然找不到目标元素; - 对于Render Props模式的
Step组件,浅渲染(shallow)不会自动执行它的子函数,所以debug里看到的[function]就是那个未执行的Render Prop函数,这也会干扰你对组件结构的断言。
具体解决方案
1. 用组件引用代替字符串查找(最可靠)
在测试文件里直接导入ProgressBar和Step组件,用组件的引用作为find的参数,这样Enzyme会通过组件的引用类型匹配,完全不依赖组件名:
// 先导入你的业务组件和第三方组件 import CaseProgress from './CaseProgress'; import ProgressBar from 'your-progressbar-path'; // 替换成实际导入路径 import Step from 'your-step-path'; // 替换成实际导入路径 let mountedComponent; beforeEach(() => { mountedComponent = shallow(<CaseProgress {...testProps}/>); }); it('renders a progress bar',() => { // 使用组件引用查找,而非字符串 const progressBars = mountedComponent.find(ProgressBar); expect(progressBars.length).toEqual(1); }); it('has 5 steps in the progress bar', () => { // 直接查找Step组件,不需要嵌套字符串 const steps = mountedComponent.find(Step); expect(steps.length).toEqual(5); });
2. 手动给组件添加displayName(可选)
如果想让debug输出显示真实的组件名,可以在测试文件里手动为第三方组件设置displayName:
import ProgressBar from 'your-progressbar-path'; ProgressBar.displayName = 'ProgressBar'; import Step from 'your-step-path'; Step.displayName = 'Step';
之后再用debug()查看,就能看到<ProgressBar>和<Step>的标识了。
3. 测试Render Props的内容(如果需要)
如果要验证Step里渲染的item.StepName,需要手动执行它的Render Prop函数:
it('renders correct step names', () => { const steps = mountedComponent.find(Step); steps.forEach((stepWrapper, index) => { // 获取Step组件的Render Prop函数 const renderProp = stepWrapper.prop('children'); // 执行函数,模拟传入accomplished属性 const stepContent = renderProp({ accomplished: true }); // 渲染函数返回的内容并断言 const contentWrapper = shallow(stepContent); expect(contentWrapper.text()).toEqual(testProps.steps[index].StepName); }); });
内容的提问来源于stack exchange,提问作者Steven Fisher
相关产品推荐
相关产品推荐

