web-dev-qa-db-fra.com

Comment testez-vous le routeur qui fait correspondre les paramètres à la plaisanterie et à l'enzyme?

Supposons que je récupère le composant suivant depuis https://www.codeday.top/2017/11/08/56644.html . Ici, j'utilise match.params pour accéder à l'identifiant. Comment rédiger un test unitaire pour ce composant teste la présence de l'élément h2 à l'aide de Jest + Enzyme + TypeScript + React.

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')
);
6
vanegeek

Utilisez includesMatchingElement

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

Envelopper tous les tests dans le contexte

Le routeur existe dans un contexte, vous pouvez donc envelopper vos tests dans un contexte et y fournir des paramètres correspondants pour tester la façon dont votre composant les récupère.

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

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

Exemple décrire:

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

});

Cela vous permet également d'ajouter éventuellement d'autres éléments au contexte et permet à l'objet de niveau supérieur de l'encapsuleur d'être votre composant (par opposition à l'encapsulation avec BrowserRouter ou StaticRouter).

0
Steve Banton