如何用酶测试react-router

IT技术 reactjs mocha.js react-router chai enzyme
2021-04-10 13:30:54

我正在使用酶 + 摩卡 + 柴来测试我的 react-redux 项目。Enzyme 提供了浅层来测试组件行为。但是我没有找到测试路由器的方法。我正在使用 react-router 如下:

<Router history={browserHistory}>
     ...
        <Route path="nurse/authorization" component{NurseAuthorization}/>
     ...
  </Route>

我想测试这个路由nurse/authorization引用NurseAuthorization组件。如何在 reactjs 项目中测试它?

编辑1

react-router用作路由器框架。

3个回答

您可以将路由器包装在一个组件中以对其进行测试。

路由.jsx

export default props => (
  <Router history={browserHistory}>
    ...
    <Route path="nurse/authorization" component{NurseAuthorization}/>
    ...
  </Route>
)

索引.js

import Routes from './Routes.jsx';
...

ReactDOM.render(<Routes />, document.getElementById('root'));

然后你必须对你的Routes组件进行浅渲染,你可以创建一个对象映射来检查路径和相关组件之间的对应关系。

路由测试.js

import { shallow } from 'enzyme';
import { Route } from 'react-router';
import Routes from './Routes.jsx';
import NurseAuthorization from './NurseAuthorization.jsx';

it('renders correct routes', () => {
  const wrapper = shallow(<Routes />);
  const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
    const routeProps = route.props();
    pathMap[routeProps.path] = routeProps.component;
    return pathMap;
  }, {});
  // { 'nurse/authorization' : NurseAuthorization, ... }

  expect(pathMap['nurse/authorization']).toBe(NurseAuthorization);
});

编辑

如果您想额外处理渲染props的情况:

const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
  const routeProps = route.props();
  if (routeProps.component) {
    pathMap[routeProps.path] = routeProps.component;
  } else if (routeProps.render) {
    pathMap[routeProps.path] = routeProps.render({}).type;
  }
  return pathMap;
}, {});

只有在您直接渲染要测试的组件(没有额外的包装器)时,它才会起作用。

<Route path="nurse/authorization" render{() => <NurseAuthorization />}/>
顺便说一句,我正在使用“反应路由器”
2021-06-02 13:30:54
@ZhaoYi Routes 必须是一个 React 组件(参见 Routes.jsx)
2021-06-02 13:30:54
这很棒!它在 App.js 中工作:从“./Routes”导入路由导出默认类 App extends Component { render() { return ( <main> <Navbar/> <div className="page-body"> <Provider store={ store}> <Routes/> </Provider> </div> </main> ); 在 index.js: import React from "react"; 从“react-dom”导入 ReactDOM;从“./App”导入应用程序;ReactDOM.render( <App />, document.getElementById('root') );
2021-06-06 13:30:54
很好的答案,但请注意,因为它不处理使用render而不是component直接使用的情况<Route path="..." render={props => <YourComponent {...props} />} />
2021-06-12 13:30:54
我按照您的指示进行操作,但在“const wrapper = Shallow(<Routes />);”行出现以下错误 - 对象不是构造函数(评估 'Component(publicProps, publicContext, updateQueue)')
2021-06-15 13:30:54

我在另一个文件中为动态路由器定义了我的路径,所以我也在测试我渲染为 Routes 的所有路由是否在我的 paths.js 常量中定义:

it('Routes should only have paths declared in src/routing/paths.js', () => {
  const isDeclaredInPaths = (element, index, array) => {
    return pathsDefined.indexOf(array[index]) >= 0;
  }
  expect(routesDefined.every(isDeclaredInPaths)).to.be.true;
});

这只会在组件成功渲染时通过:它与 Redux 和 react-router 一起使用,包括钩子。

import React from "react";

import { expect } from "chai";
import { mount } from "enzyme";
import { MemoryRouter, Route } from "react-router-dom";
import { createMockStore } from "redux-test-utils";
import { Provider } from "react-redux";


...
describe("<MyComponent />", () => {
    it("renders the component", () => {
    let props = {
      index: 1,
      value: 1
    };
    let state = {};

    const wrapper = mount(
      <Provider store={createMockStore(state)}>
        <MemoryRouter initialEntries={["/s/parameter1"]}>
          <Route path="/s/:camera">
            <MyComponent {...props} />
          </Route>
        </MemoryRouter>
      </Provider>
    );

    expect(wrapper.find(ProcessedFrames.WrappedComponent)).to.have.lengthOf(1);
  });
});