ユニットテストはコンポーネントをルーターで反応させます(jest、酵素)

withRouter(Component)を使用してコールにラップされたリアクティブコンポーネントの単体テストを開発するときに、そのようなコンポーネントはルーターのコンテキストにのみ存在できるというエラーメッセージが表示されました。 この問題の解決策は非常に単純であり、原則として質問をするべきではありません。 何らかの理由で、ドキュメントへのリンクhttps://reacttraining.com/react-router/web/guides/testing Googleは、断念して配布を拒否しました。 これは私をまったく驚かせません。なぜなら、 ドキュメントは、SSRなしの純粋なSPAアプリケーションとして記述されており、検索エンジンの観点からは次のようになります。



画像を表示
画像



十分なドキュメントがあれば、誰でもこれを読むことができます。 そして、私自身のために、カットの下でいくつかのメモを作成します。



テストされたコンポーネント(ページネーター)は、パラメーターとして、行数-合計、ページ上、および現在のページの数を取ります。 次の形式のリンクを使用してコンポーネントを形成する必要があります。





import React from 'react'; import _ from 'lodash'; import { withRouter } from 'react-router-dom'; import Link from '../asyncLink'; // eslint-disable-line function prepareLink(match, page) { const { url } = match; const basePath = url.replace(/\/(page\/[0-9]+)?$/, ''); if (page === 1) { return basePath || '/'; } return `${basePath}/page/${page}`; } const Pagination = ({ count, pageLength, page, match }) => ( // eslint-disable-line react/prop-types, max-len count && pageLength && count > pageLength ? <nav> <ul className="pagination"> { _.range(1, 1 + Math.ceil(count / pageLength)).map(index => ( <li className={`page-item${index === page ? ' active' : ''}`} key={index}> <Link className="page-link" to={prepareLink(match, index)}> {index} </Link> </li>)) } </ul> </nav> : null ); export default withRouter(Pagination);
      
      





このコンポーネントはmatchプロパティを使用します。これは、 withRouter(Pagination)



呼び出しでラップされたコンポーネントでのみ使用できます。 テストするときは、テスト用の特別なルーター(MemoryRouter)を使用してコンテキストを作成する必要があります。 また、コンポーネントを適切なルートルートに配置して、一致を形成します。



 /* eslint-disable no-undef, function-paren-newline */ import React from 'react'; import { MemoryRouter, Route } from 'react-router-dom'; import { configure, mount } from 'enzyme'; import renderer from 'react-test-renderer'; import Adapter from 'enzyme-adapter-react-16'; import Pagination from '../../../src/react/components/pagination'; configure({ adapter: new Adapter() }); test('Paginator snapshot', () => { const props = { count: 101, pageLength: 10, page: 10, }; const component = renderer.create( <MemoryRouter initialEntries={['/', '/page/10', '/next']} initialIndex={1}> <Route path="/page/:page"> <Pagination {...props} /> </Route> </MemoryRouter>, ); const tree = component.toJSON(); expect(tree).toMatchSnapshot(); }); test('Paginator for root route 1st page', () => { const props = { count: 101, pageLength: 10, page: 1, }; const component = mount( <MemoryRouter initialEntries={['/before', '/', '/next']} initialIndex={1}> <Route path="/"> <Pagination {...props} /> </Route> </MemoryRouter>, ); expect(component.find('li.active').find('a').prop('href')).toEqual('/'); expect(component.find('li').first().find('a').prop('href')).toEqual('/'); }); test('Paginator for root route 2nd page', () => { const props = { count: 101, pageLength: 10, page: 2, }; const component = mount( <MemoryRouter initialEntries={['/', '/page/2', '/next']} initialIndex={1}> <Route path="/page/:page"> <Pagination {...props} /> </Route> </MemoryRouter>, ); expect(component.find('li.active').find('a').prop('href')).toEqual('/page/2'); expect(component.find('li').first().find('a').prop('href')).toEqual('/'); }); test('Paginator for some route 1st page', () => { const props = { count: 101, pageLength: 10, page: 1, }; const component = mount( <MemoryRouter initialEntries={['/', '/some', '/next']} initialIndex={1} context={{}}> <Route path="/some"> <Pagination {...props} /> </Route> </MemoryRouter>, ); expect(component.find('li.active').find('a').prop('href')).toEqual('/some'); expect(component.find('li').first().find('a').prop('href')).toEqual('/some'); }); test('Paginator for /some route 2nd page', () => { const props = { count: 101, pageLength: 10, page: 2, }; const component = mount( <MemoryRouter initialEntries={['/', '/some/page/2', '/next']} initialIndex={1}> <Route path="/some/page/:page"> <Pagination {...props} /> </Route> </MemoryRouter>, ); expect(component.find('li.active').find('a').prop('href')).toEqual('/some/page/2'); expect(component.find('li').first().find('a').prop('href')).toEqual('/some'); });
      
      





MemoryRouterには、コンポーネントの「想像上の」履歴が含まれており、これに沿って前後に移動できます。 開始インデックスは、 initialIndex



プロパティによって設定されます。



テストでは、airbnb(酵素)の一般的なライブラリを使用して、jestコマンドを実行します。

最初の開始時のjestフレームワークは、コンポーネントのスナップショットを形成し、レンダリングの結果のドキュメントと比較します。



  const tree = component.toJSON(); expect(tree).toMatchSnapshot();
      
      





DOM要素を検索および分析するための酵素ライブラリコマンドは、たとえばjqueryほど簡潔ではありません。 それにもかかわらず、すべてが非常に便利です。



apapacy@gmail.com

2018年3月5日。



All Articles