Enzyme / React テストで render と shallow をいつ使用すればよいですか? 質問する

Enzyme / React テストで render と shallow をいつ使用すればよいですか? 質問する

この質問を投稿する前に、sqa stackexchange で検索してみましたが、shallow と render に関する投稿は見つかりませんでした。誰かがここで私を助けてくれることを願っています。

React コンポーネントのテストで shallow と render はいつ使用すればよいでしょうか? airbnb のドキュメントに基づいて、2 つの違いについていくつかの意見を述べました。

  1. 浅いテストはコンポーネントをテストするためユニットとしてしたがって、「親」コンポーネントに使用する必要があります。(例: テーブル、ラッパーなど)

  2. レンダリングは子コンポーネント用です。

私がこの質問をした理由は、どちらを使用すべきか判断するのに苦労しているからです(ドキュメントでは、それらは非常に似ていると書かれていますが)

では、特定のシナリオでどちらを使用すればよいかはどうすればわかるのでしょうか?

ベストアンサー1

酵素によるとドキュメント:

mount(<Component />)完全な DOM レンダリングは、DOM API と対話する可能性のあるコンポーネントがある場合や、コンポーネントを完全にテストするために完全なライフサイクルが必要な場合 (つまり、componentDidMount など) に最適です。

shallow(<Component />)浅いレンダリングは、コンポーネントをユニットとしてテストするように制限し、テストが子コンポーネントの動作を間接的にアサートしないようにするのに役立ちます。

renderこれはReactコンポーネントをレンダリングするために使用されます静的HTML結果として得られる HTML 構造を分析します。

浅いレンダリングでも基礎となる「ノード」を見ることができるので、例えば、次のような(少し不自然な)例を実行することができます。エイバスペックランナーとして:

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 />)

このテストではシノンコンポーネントをスパイする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();
});

上記は通用しない浅いレンダリングまたは与える

renderHTML のみが提供されるため、次のようなこともできます。

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

    // insert Test component here...

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

おすすめ記事