web-dev-qa-db-ja.com

Enzyme / Reactテストでrenderとshallowを使用する必要があるのはいつですか?

この質問を投稿する前に、私はsqa stackexchangeで検索しようとしましたが、浅い場所についての投稿を見つけず、そこでレンダリングするので、誰かが私を助けてくれることを願っています。

Reactコンポーネントのテストで浅いレンダリングを使用する必要があるのはいつですか? airbnbのドキュメントに基づいて、2つの違いについて意見を述べました。

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

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

私がこの質問をした理由は、どちらを使用すべきかを理解するのが難しいためです(ドキュメントは非常に似ていると述べていますが)

それで、特定のシナリオでどれを使用するかをどのように知るのですか?

82
Cyval

酵素ごと docs

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

vs.

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

vs.

renderは、reactコンポーネントをstatic 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));
});

renderingsetting propsfinding selectors、さらには合成イベントはすべて浅いレンダリングでサポートされているため、ほとんどの場合それを使用できます。

ただし、コンポーネントのライフサイクル全体を取得することはできません。そのため、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();
});

上記はshallow renderingまたはrenderで渡されません

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);
});

お役に立てれば!

141
4m1r

Shallow()とmount()の違いは、shallow()がレンダリングする子コンポーネントから分離してコンポーネントをテストする一方で、mount()がさらに深くなり、コンポーネントの子をテストすることです。これは、親コンポーネントがレンダリングに失敗した別のコンポーネントをレンダリングする場合、親でのレンダリングが引き続きパスすることを意味します。

5
Shyam Kumar