web-dev-qa-db-ja.com

withRouterで囲まれた反応コンポーネントのテスト(jest / enzymeを使用することが望ましい)

私はReactコンポーネントを持っています

module.exports = withRouter(ManageProfilePage);

私のルートは次のとおりです。

<Route path="/" component={AdrApp}>
    <IndexRoute component={Login}/>
    <Route component={CheckLoginStatus}>
        <Route path="manage-profiles/:profileId" component=
        {ManageProfilesPage}/>
     </Route>
    <Route path="*" component={notFoundPage}/>
</Route>

ルーターのライフサイクルメソッドを1回使用する必要があるため、withRouterが必要です。

class ManageProfilePage extends React.Component {
    componentDidMount() {
    this.props.router.setRouteLeaveHook(this.props.route, () => {
      ...
    })
    render(){
    ... 
    }
}

Jest/Enzymeを使用してこのコンポーネントをテストする必要があり、以下のようにテストケースを作成しました。

describe('manage profile page test suite', () => {


    it('snapshot test', () => {

        const setRouteLeaveHook =jest.fn();

        let wrapper = shallow(
            <ManageProfilePage params={{id : 25, router: 
        setRouteLeaveHook}}/>
        );
      expect(wrapper).toMatchSnapshot();
    })
   }) 

問題は、1レベルの深さでレンダリングされていないことです。以下のスナップショットを貼り付けています。

exports[`manage drug term page test suites snapshot test 1`] = `
<ManageProfilePage
  params={
    Object {
      "id": 25,
      "router": [Function],
    }
  }
/>
`;

ManageProfilePageを少なくとも1レベル深くレンダリングできるように、テストケースを作成する別の方法はありますか? WithRouterで囲まれているためレンダリングできませんか?これらのタイプのコンポーネントをどのようにテストしますか?

20
Amol Aggarwal

通常、このようなコンポーネントをテストしようとすると、WithRouter内にラップされているためレンダリングできません(WithRouterは、コンポーネント内で直接使用される一致、ルート、履歴などのルータープロップを提供するコンポーネントのラッパーです)。 module.exports = withRouter(ManageProfilePage);

そのようなコンポーネントをレンダリングするには、WrappedComponentキーワードを使用してラップされたコンポーネントをレンダリングするように明示的に指示する必要があります。例えばスナップショットテストには以下のコードを使用します。

describe('manage profile page test suite', () => {


    it('snapshot test', () => {

        const setRouteLeaveHook =jest.fn();

        let wrapper = shallow(
            <ManageProfilePage.WrappedComponent params={{id : 25, router: 
        setRouteLeaveHook}}/>
        );
      expect(wrapper).toMatchSnapshot();
    })
   }) 

これは、WithRouter内でラップされたコンポーネントであるManageProfilePageに対して、浅いレンダリングを実行するように酵素に指示します(浅いレンダリングはその特定のコンポーネントのみをレンダリングし、子コンポーネントをスキップします)。

34
Amol Aggarwal

浅いレンダリングでは、1つのレベルのみがレンダリングされます。これは、その仕様の一部です。

ツリー全体をレンダリングするMountを使用できますが、レンダリングするレベルの深さを制限できるとは思いません。

いずれにせよ、高次コンポーネントを使用するときは、通常、基本コンポーネントもエクスポートします(ラップする前)。この方法で、ラッパーなしですべてのテストを実行し、必要なプロバイダーにモックを渡すことができます。

reduxを使用したConnectコンポーネントでも同じことが言えます。通常のコンポーネントをエクスポートし、接続されているコンポーネントではなく、その上でさまざまなプロップをテストします。

また、いくつかのwith...ラッパーは内部インスタンスを公開しません(一部は公開しますが、一部は公開しません)。そのため、ラッパーではなく独自のコンポーネントでテストすることも役立ちます。

2
Patrick