你如何用开玩笑和酶测试路由器匹配参数?

时间:2018-02-20 22:52:32

标签: reactjs typescript react-router jestjs enzyme

说我有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')
);

2 个答案:

答案 0 :(得分:4)

使用containsMatchingElement

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

答案 1 :(得分:1)

在上下文中包装所有测试

路由器存在于上下文中,因此您可以在上下文中包装测试并为其提供匹配参数,以测试组件如何拾取它们。

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

示例描述:

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进行包装相反)