Enzyme 是一个流行的 React 组件测试工具,但是在测试父组件中嵌套的子组件时,经常会出现渲染错误的问题。本文将介绍这种错误的原因,并提供一些解决方案。
Enzyme 测试中的渲染错误
让我们首先来看一个使用 Enzyme 进行组件测试时的常见错误:
it('renders Child component', () => { const wrapper = shallow(<Parent />); expect(wrapper.find(Child)).toHaveLength(1); });
假设我们有一个 Parent
组件,它包含一个 Child
组件。我们期望上述测试代码能够通过。但是实际上,它会返回以下错误:
Expected: 1 Received: 0
这是因为,当 Parent
组件被浅渲染时,它内部的 Child
组件并没有被渲染,所以在 Enzyme 的虚拟 DOM 中无法找到它。
Enzyme 的虚拟 DOM 和渲染方式
为了更好地理解这个问题,我们需要了解 Enzyme 的虚拟 DOM 和渲染方式。
Enzyme 提供了三种渲染方式:shallow、mount 和 render。它们分别对应了 React 组件的三种渲染方式:
shallow
只渲染当前组件,不会渲染子组件,返回的是组件的浅渲染结果。mount
渲染整个组件树,并返回一个渲染后的 DOM 对象。render
与mount
类似,但返回的是一个静态 HTML 字符串。
当我们使用 shallow 进行组件测试时,Enzyme 只会渲染当前组件,而不会渲染子组件。这意味着,被渲染的组件只会包含当前组件的 DOM 节点,而不会包含子组件的虚拟 DOM。
解决渲染错误的问题
既然我们了解了问题的原因,现在就是时候找到解决这个问题的方法了。这里给出一些不同的解决方案:
使用 mount 代替 shallow
如果你希望在测试中检查子组件,则可以使用 mount
方法进行渲染。
it('renders Child component', () => { const wrapper = mount(<Parent />); expect(wrapper.find(Child)).toHaveLength(1); });
使用 mount
进行完整的渲染,这样子组件也会被渲染,能够通过测试。
使用 stubProps 突破组件屏障
对于某些情况,mount
中渲染整个组件树可能会导致测试变得缓慢。此时,一个更好的选择是使用 stubProps
突破组件屏障,允许我们在尽可能少的级别上测试组件。以下是 stubProps
的用法:
it('renders Child component', () => { const wrapper = shallow(<Parent />); const childWrapper = wrapper .find(Child) .dive({ stubbedProp: 'myStub' }); expect(childWrapper).toHaveLength(1); });
在上面的代码中,dive
方法会将父组件的 props 传递给子组件。通过这种方式,我们可以访问子组件的虚拟 DOM,后面的测试也可以使用 childWrapper
来进行。
使用 childAt,手动遍历子组件
还有一种方式是使用 childAt
来手动遍历子组件,然后对其进行测试。
it('renders Child component', () => { const wrapper = shallow(<Parent />); const child = wrapper .children() .at(0) .dive(); expect(child.type()).toEqual(Child); });
这种方法需要你知道你的 Child
组件在父组件中的位置。你需要使用 children
来获取 Parent
组件的所有子节点,然后使用 at
来选择 Child
子节点。当你针对多个子组件进行测试时,这种方法可能会变得笨重和不可维护。
结论
这篇文章介绍了在 Enzyme 组件测试中遇到的常见渲染错误。我们学习了 Enzyme 的三种渲染方式,以及如何使用 mount
和 stubProps
方法来解决这个问题。
最后,使用哪种方法取决于你的具体情况。请根据你的项目实际情况来选择使用不同的方法。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/674966b6a1ce0063545c2e5b