Reactjs 你如何用jest和Ezyme测试路由器匹配参数?

Reactjs 你如何用jest和Ezyme测试路由器匹配参数?,reactjs,typescript,react-router,jestjs,enzyme,Reactjs,Typescript,React Router,Jestjs,Enzyme,假设我有以下我从中抓取的组件。在这里,我使用match.params来访问id。我如何为该组件编写单元测试?使用Jest+酶+类型脚本+反应来测试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 c

假设我有以下我从中抓取的组件。在这里,我使用match.params来访问id。我如何为该组件编写单元测试?使用Jest+酶+类型脚本+反应来测试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')
);
import*as React from'React';
从“react dom”导入*作为react dom;
从“react Router dom”导入{Route,BrowserRouter as Router,Link,match};
//为多个页面定义React组件
类Home扩展了React.Component{
render(){
返回(
家
转到详细信息
);
}
}
接口详细信息参数{
id:字符串;
}
接口详细信息计划{
必需:字符串;
匹配?:匹配;
}
类详细信息扩展了React.Component{
render(){
常量匹配=this.props.match;
如果(匹配){
返回(
{match.params.id}的详细信息
回家
);
}否则{
返回(
威尔·罗宾逊
回家
)
}
}
}
ReactDOM.render(
} />
,document.getElementById('root'))
);
使用

const wrapper=shallow(
);
expect(wrapper.containsMatchingElement(1的详细信息)).toBeTruthy();
在上下文中包装所有测试 路由器存在于上下文中,所以您可以将测试包装在上下文中,并向其提供匹配参数,以测试组件如何拾取它们

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

});
从“React”导入React;
从“../../src/TableC”导入{TableC};
从“../testhelp/contextWrap”导入{mountWrap,shallowWrap};
从“/mockdata”导入{expectedProps}
描述('表',()=>{
让道具;
let组件;
让路线={
地点:{},
匹配:{[match OBJ HERE]}
}
常量wrappedMount=()=>mountWrap(,路径);
在每个之前(()=>{
道具={
查询:{
数据:tableData,
refetch:jest.fn(),
},
};
if(component)component.unmount();
});
测试('应使用正确的道具调用DeepTable',()=>{
让路线={
地点:{},
匹配:{[在测试之前在此更新匹配对象]}
}
const wrapper=wrappedMount();
expect(wrapper.find('DeepTable').props()).toEqual(expectedProps);
});
});

这还允许您选择向上下文添加其他内容,并允许包装中的顶级对象作为您的组件(与使用BrowserRouter或StaticRouter包装不同)

您可以使用路径或url设置位置,还是只使用window.location=''我想您只需提供
匹配
属性即可。从真实url到
match
prop的转换是路由库的工作,因此我们不需要对其进行测试。@有什么方法可以创建匹配对象而不是对其进行硬编码?像我不知道的
createBrowserHistory()
,这个文档--只是告诉我们如何使用它,而不是如何创建它。您是否有contextWrap代码的typescript友好版本。对于ES7,请在
路由器(路由)
上使用扩展运算符。e<代码>路由器(路由)
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);
  });

});