React容器含子组件测试失败问题求助
解决AddProduct组件测试中无法找到Card组件的问题
看起来你的测试遇到了两个核心问题:shallow渲染的层级限制和React组件命名规范问题,下面一步步帮你排查解决:
问题分析
- Shallow渲染的特性限制:你用
shallow渲染了MemoryRouter包裹的AddProduct,但shallow只会渲染当前组件的第一层结构。也就是说,你的wrapper现在指向的是MemoryRouter组件,它的子元素是AddProduct,但AddProduct的内部结构并没有被展开渲染,所以直接在wrapper里找card组件肯定找不到。 - 组件命名大小写错误:React规定组件必须以大写字母开头(否则会被当作普通HTML标签处理),你导入的
card是小写,这会导致Enzyme无法识别它是React组件,自然也匹配不到。
解决方案
第一步:修正组件导入的大小写
首先把组件导入的名字改成大写(假设你的组件文件里导出的是大写的Card):
import Card from '../../components/UI/card/card';
第二步:调整测试的渲染方式
根据你的AddProduct是否依赖路由功能,选择下面两种方案之一:
方案1:如果AddProduct不依赖路由(不需要MemoryRouter)
直接shallow渲染AddProduct即可,不需要包裹MemoryRouter:
describe('<AddProduct />', () => { let wrapper; beforeEach(() => { // 直接渲染AddProduct,去掉MemoryRouter wrapper = shallow(<AddProduct title="hi" />); }); it('should render the card when its load', () => { expect(wrapper.find(Card)).toHaveLength(1); }); });
方案2:如果AddProduct依赖路由(必须用MemoryRouter)
这种情况下,你需要用mount来渲染完整的组件树,或者用shallow结合dive()来深入渲染AddProduct:
方式A:使用mount渲染
describe('<AddProduct />', () => { let wrapper; beforeEach(() => { wrapper = mount( <MemoryRouter> <AddProduct title="hi" /> </MemoryRouter>, ); }); it('should render the card when its load', () => { // 先找到AddProduct组件,再在它内部找Card expect(wrapper.find(AddProduct).find(Card)).toHaveLength(1); }); });
方式B:使用shallow + dive()
describe('<AddProduct />', () => { let wrapper; beforeEach(() => { wrapper = shallow( <MemoryRouter> <AddProduct title="hi" /> </MemoryRouter>, ); }); it('should render the card when its load', () => { // 找到AddProduct后,用dive()深入渲染它的内部结构 expect(wrapper.find(AddProduct).dive().find(Card)).toHaveLength(1); }); });
为什么原来的代码不生效?
你之前的wrapper是MemoryRouter的浅渲染实例,它的子元素只有AddProduct,但AddProduct的内部(包括Card组件)并没有被shallow渲染出来,所以wrapper.find(card)会在MemoryRouter的直接子元素里查找,自然找不到Card。
内容的提问来源于stack exchange,提问作者Naresh Manthena
相关产品推荐
相关产品推荐

