什么时候应该在酶/反应测试中使用渲染和浅化?


95

在发布此问题之前,我曾尝试在sqa stackexchange中进行搜索,但未找到有关浅层和渲染的文章,因此希望有人能在这里为我提供帮助。

什么时候应该在测试反应组件时使用浅层渲染?根据airbnb文档,我对两者的区别提出了一些意见:

  1. 由于浅层将组件作为一个整体进行测试,因此应将其用于“父级”组件。(例如桌子,包装纸等)

  2. 渲染用于子组件。

我问这个问题的原因是,我很难确定应该使用哪一个(尽管文档说它们非常相似)

那么,我怎么知道在特定情况下使用哪个呢?


2
shallow()和mount()之间的区别在于,shallow()会将组件与其呈现的子组件隔离开来测试组件,而mount()会更深一些并测试组件的子组件。对于shallow(),这意味着如果父组件渲染了另一个无法渲染的组件,则父组件上的shallow()渲染仍将通过。
Shyam Kumar,

Answers:


160

根据酶文档

mount(<Component />) 对于完整的DOM呈现,对于您的组件可能与DOM API交互或可能需要完整生命周期才能完全测试组件的使用案例(例如componentDidMount等)非常理想。

shallow(<Component />) 浅呈现对于约束自己将组件作为一个单元进行测试非常有用,并可以确保测试不会间接断言子组件的行为。

render用于将响应组件呈现为静态HTML并分析生成的HTML结构。

您仍然可以在浅层渲染中看到底层的“节点”,因此,例如,您可以使用AVA作为规范运行器来执行类似(略做作)的示例:

let wrapper = shallow(<TagBox />);

const props = {
    toggleValue: sinon.spy()
};

test('it should render two top level nodes', t => {
    t.is(wrapper.children().length, 2);
});

test('it should safely set all props and still render two nodes', t => {
    wrapper.setProps({...props});
    t.is(wrapper.children().length, 2);
});

test('it should call toggleValue when an x class is clicked', t => {
    wrapper.setProps({...props});
    wrapper.find('.x').last().simulate('click');
    t.true(props.toggleValue.calledWith(3));
});

请注意,浅层渲染支持渲染设置道具查找选择器甚至是合成事件,因此大多数时候您都可以使用它。

但是,您将无法获得组件的完整生命周期,因此,如果您希望在componentDidMount中发生某些事情,则应使用mount(<Component />);

此测试使用Sinon监视组件的componentDidMount

test.only('mount calls componentDidMount', t => {

    class Test extends Component {
        constructor (props) {
            super(props);
        }
        componentDidMount() {
            console.log('componentDidMount!');
        }
        render () {
            return (
                <div />
            );
        }
    };

    const componentDidMount = sinon.spy(Test.prototype, 'componentDidMount');
    const wrapper = mount(<Test />);

    t.true(componentDidMount.calledOnce);

    componentDidMount.restore();
});

以上将不会通过浅渲染渲染

render 只会为您提供html,因此您仍然可以执行以下操作:

test.only('render works', t => {

    // insert Test component here...

    const rendered = render(<Test />);
    const len = rendered.find('div').length;
    t.is(len, 1);
});

希望这可以帮助!


1
我仍然没有得到100%,为什么这三个动词会带来不同的方法。例如,可以在浅层而不是在渲染中使用wrapper.getNode()。有什么解释/链接/文档/博客,可以帮助我实现这一目标吗?
Paulquappe

@HenryZhu,从文档中应该清楚的是,渲染比浅层更复杂,因为它实际上是在模仿特定组件节点的DOM树
AGE

11
从v2到v3的酶迁移已默认在浅表以及github.com/airbnb/enzyme/blob/master/docs/guides/…中启用
Abhinav Singi


9

shallow()和mount()之间的区别在于,shallow()会将组件与其呈现的子组件隔离开来测试组件,而mount()会更深一些并测试组件的子组件。

对于shallow(),这意味着如果父组件渲染了另一个无法渲染的组件,则父组件上的shallow()渲染仍将通过。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.