web-dev-qa-db-ja.com

jestと酵素を使用してルーターのマッチパラメーターをどのようにテストしますか?

https://www.codeday.top/2017/11/08/56644.html から取得した次のコンポーネントがあるとします。ここでは、match.paramsを使用してIDにアクセスしています。このコンポーネントの単体テストを作成して、Jest + Enzyme + TypeScript + Reactを使用してh2要素の存在をテストするにはどうすればよいですか。

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Route, BrowserRouter as Router, Link, match } from 'react-router-dom';

// define React components for multiple pages
class Home extends React.Component<any, any> {
  render() {
    return (
      <div>
        <div>HOME</div>
        <div><Link to='/details/id123'>Goto Details</Link></div>
      </div>);
  }
}

interface DetailParams {
  id: string;
}

interface DetailsProps {
  required: string;
  match?: match<DetailParams>;
}

class Details extends React.Component<DetailsProps, any> {
  render() {
    const match = this.props.match;
    if (match) {
      return (
        <div>
          <h2>Details for {match.params.id}</h2>
          <Link to='/'>Goto Home</Link>
        </div>
      );
    } else {
      return (
        <div>
          <div>Error Will Robinson</div>
          <Link to='/'>Goto Home</Link>
        </div>
      )
    }
  }
}

ReactDOM.render(
  <Router>
    <div>
      <Route exact path="/" component={Home} />
      <Route exact path="/details/:id" component={(props) => <Details required="some string" {...props} />} />
    </div>
  </Router>

  , document.getElementById('root')
);
9
vanegeek

containsMatchingElement を使用します

const wrapper = shallow(
  <Details
    required={true}
    match={{params: {id: 1}, isExact: true, path: "", url: ""}}
  />
);
expect(wrapper.containsMatchingElement(<h2>Details for 1</h2>)).toBeTruthy();
5
paibamboo

コンテキスト内のすべてのテストをラップする

ルーターはコンテキスト内に存在するため、コンテキスト内でテストをラップし、それにマッチパラメーターを指定して、コンポーネントがそれらをどのように選択するかをテストできます。

import { BrowserRouter } from 'react-router-dom';
import { shape } from 'prop-types';
import { mount } from 'enzyme';

// Instantiate router context
const router = (route) => ({
  history: new BrowserRouter().history,
  route,
});

const createContext = (route) => ({
  context: { router(route) },
  childContextTypes: { router: shape({}) },
});

export function mountWrap(node, route) {
  return mount(node, createContext(route));
}

例の説明:

import React from 'react';
import { TableC } from '../../src/tablec';
import { mountWrap, shallowWrap } from '../testhelp/contextWrap';
import { expectedProps } from './mockdata'

describe('Table', () => {
  let props;
  let component;
  let route = {
    location: {},
    match: {[MATCH OBJ HERE]}
  }

  const wrappedMount = () => mountWrap(<TableC {...props} />, route);

  beforeEach(() => {
    props = {
      query: {
        data: tableData,
        refetch: jest.fn(),
      },
    };
    if (component) component.unmount();
  });

  test('should call a DeepTable with correct props', () => {
    let route = {
      location: {},
      match: {[UPDATE MATCH OBJ HERE BEFORE TEST]}
    }
    const wrapper = wrappedMount();
    expect(wrapper.find('DeepTable').props()).toEqual(expectedProps);
  });

});

これにより、オプションでコンテキストに他のものを追加することができ、ラッパーの最上位オブジェクトをコンポーネントにすることができます(BrowserRouterまたはStaticRouterでラップするのではなく)

1
Steve Banton