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

Cyv*_*val 87 testing meteor chai reactjs enzyme

在发布这个问题之前,我试图在sqa stackexchange中搜索,但我发现没有关于浅的帖子并在那里渲染,所以我希望有人可以帮助我.

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

  1. 由于浅层是将组件作为一个单元进行测试,因此它应该用于"父"组件.(例如桌子,包装等)

  2. 渲染用于子组件.

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

那么,我如何知道在特定场景中使用哪一个?

4m1*_*m1r 148

根据Enzyme docs:

mount(<Component />) 对于完全DOM渲染非常适合您拥有可能与DOM apis交互的组件的情况,或者可能需要整个生命周期才能完全测试组件(即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));
});
Run Code Online (Sandbox Code Playgroud)

请注意,浅渲染支持渲染,设置道具查找选择器甚至合成事件,因此大多数情况下您可以使用它.

但是,您将无法获得组件的整个生命周期,因此如果您希望在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();
});
Run Code Online (Sandbox Code Playgroud)

以上不会通过浅渲染渲染

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);
});
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 从v2到v3的酶迁移使生命周期方法默认处于浅层状态,以及https://github.com/airbnb/enzyme/blob/master/docs/guides/migration-from-2-to-3.md (9认同)
  • 对差异的很好的额外解释在这里 https://github.com/airbnb/enzyme/issues/465#issuecomment-227697726 和这里 https://github.com/airbnb/enzyme/issues/465#issuecomment-229116418 (2认同)

Shy*_*mar 7

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

  • 当我测试组件的“props”时,我应该使用“shallow”和“mount”吗? (2认同)