【问题标题】:How do you test router match params with jest and enzyme?你如何用 jest 和酵素测试路由器匹配参数?
【发布时间】:2018-07-31 10:05:29
【问题描述】:

假设我有以下从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')
);

【问题讨论】:

    标签: reactjs typescript react-router jestjs enzyme


    【解决方案1】:

    使用containsMatchingElement

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

    【讨论】:

    • 你可以使用路径或url来设置位置还是只使用window.location = 'localhost:3000/foo'
    • 我认为你只需要提供 match 道具。从真实的url转换成match prop是路由库的工作,所以我们不需要测试。
    • @paibamboo 有什么方法可以创建匹配对象而不是硬编码吗?点赞createBrowserHistory()
    • 我不知道,这个文档 - github.com/ReactTraining/react-router/blob/master/packages/… - 只是告诉我们如何使用它,而不是如何创建它。
    【解决方案2】:

    将所有测试包装在上下文中

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

    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 包装)

    【讨论】:

    • 你有没有为 contextWrap.ts 提供的代码的 typescript 友好版本
    • 对于 ES7,在 router(route) 上使用扩展运算符,即。 e. ...router(route).
    【解决方案3】:
    const wrapper = mount(
      <MemoryRouter initialEntries={['/1234']}>
        <Route exact path="/:id/" component={Details} />
      </MemoryRouter>
    );
    

    【讨论】:

    猜你喜欢
    • 2023-04-10
    • 2021-07-06
    • 2020-08-12
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多