在发布这个问题之前,我尝试在 sqa stackexchange 中搜索,但我没有找到关于浅层和渲染的帖子,所以我希望有人能在这里帮助我。
我什么时候应该在测试反应组件时使用浅层和渲染?根据airbnb docs,我对两者的区别提出了一些看法:
由于 shallow 将组件作为一个单元进行测试,因此它应该用于“父”组件。(例如表格、包装器等)
渲染用于子组件。
我问这个问题的原因是我很难弄清楚我应该使用哪个(尽管文档说它们非常相似)
那么,我如何知道在特定场景中使用哪一个呢?
根据酶文档:
mount(<Component />)
对于完整的 DOM 渲染非常适合您的组件可能与 DOM api 交互的用例,或者可能需要完整的生命周期才能完全测试组件(即 componentDidMount 等)
对比
shallow(<Component />)
for 浅渲染有助于限制您将组件作为一个单元进行测试,并确保您的测试不会间接断言子组件的行为。
对比
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);
});
希望这可以帮助!
shallow() 和 mount() 之间的区别在于,shallow() 将组件与它们渲染的子组件隔离开来,而 mount() 更深入地测试组件的子组件。
对于 shallow() 这意味着如果父组件渲染另一个无法渲染的组件,那么在父组件上的 shallow() 渲染仍然会通过。