Enzyme 中的 mount 和 shallow 在测试 React 组件时的实际应用对比
在 React 开发中,测试组件是非常重要的一部分。而 Enzyme 是 React 的一款测试工具,提供了两种测试方式:mount 和 shallow。
mount 和 shallow 最大的区别在于渲染的深度。mount 会渲染出组件及其所有子组件,而 shallow 只会渲染出当前组件,深度只有一层。那么这两种方式该如何选择呢?
选择 mount 还是 shallow?
mount 确实更加完整地模拟了组件的真实渲染,但由于渲染的深度,使得测试变慢,且依赖组件间的关系,容易受到其他组件的影响,甚至有可能出现 unmount 的情况。一般来说,mount 可用于大型应用程序或整个 React 组件树中的根组件的测试。
而 shallow 只渲染当前组件,渲染速度相对 mount 来说更快,可以在较短的时间内得出测试结果,且由于其相对独立的渲染机制,不会受到其他组件的影响,避免了 unmount 的问题。一般来说,shallow 可用于小型应用程序或单个 React 组件的测试。
示例代码
下面将给出一个示例,来帮助更好地理解 mount 和 shallow。
在这个示例中,我们有一个 Button 组件以及一个 Func 组件。Button 组件需要在点击后调用 Func。首先我们来看一下 mount 的代码:
// www.javascriptcn.com code example
import { mount } from 'enzyme';
import Button from './Button';
import Func from './Func';
describe('Button Component Test - Mount', () => {
let wrapper;
const mockFn = jest.fn();
beforeEach(() => {
wrapper = mount(<Button onClick={mockFn} />);
});
it('component should render 2 elements', () => {
expect(wrapper.find('button')).toHaveLength(1);
expect(wrapper.find(Func)).toHaveLength(1);
});
it('component should call function on click', () => {
wrapper.find('button').simulate('click');
expect(mockFn).toHaveBeenCalled();
});
it('component should unmount', () => {
wrapper.unmount();
expect(wrapper.find('button')).toHaveLength(0);
expect(wrapper.find(Func)).toHaveLength(0);
});
});该测试代码会测试 Button 组件是否正常渲染,并是否调用了 mock 函数。同时还测试了组件能否正常 unmount。
接下来看一下 shallow 的代码:
// www.javascriptcn.com code example
import { shallow } from 'enzyme';
import Button from './Button';
import Func from './Func';
describe('Button Component Test - Shallow', () => {
let wrapper;
const mockFn = jest.fn();
beforeEach(() => {
wrapper = shallow(<Button onClick={mockFn} />);
});
it('component should render 2 elements', () => {
expect(wrapper.find('button')).toHaveLength(1);
expect(wrapper.find(Func)).toHaveLength(1);
});
it('component should call function on click', () => {
wrapper.find('button').simulate('click');
expect(mockFn).toHaveBeenCalled();
});
it('component should not unmount', () => {
expect(wrapper.find('button')).toHaveLength(1);
expect(wrapper.find(Func)).toHaveLength(1);
});
});同样的测试逻辑,但在 shallow 中,我们没有进行 unmount 测试,因为 shallow 实例不会因为该组件的卸载而被卸载掉。其他测试差不多。
结语
在实际使用时,我们需要根据具体的测试情况选择 mount 或者 shallow。对于具有多层嵌套,并且移除和注入实际 DOM 以及事件处理的测试,mount 是合适的;而对于组件间相互独立,且没有进行实际渲染以及处理事件的情况,shallow 是更好的选择。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d02855e46428fe9ecd5abc