如何用酶测试反应路由器

Posted

技术标签:

【中文标题】如何用酶测试反应路由器【英文标题】:How to test react-router with enzyme 【发布时间】:2017-05-22 17:41:19 【问题描述】:

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

<Router history=browserHistory>
     ...
        <Route path="nurse/authorization" componentNurseAuthorization/>
     ...
  </Route>

我想测试这条路由nurse/authorization 参考NurseAuthorization 组件。如何在 reactjs 项目中测试?

EDIT1

我使用react-router 作为路由器框架。

【问题讨论】:

【参考方案1】:

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

Routes.jsx

export default props => (
  <Router history=browserHistory>
    ...
    <Route path="nurse/authorization" componentNurseAuthorization/>
    ...
  </Route>
)

index.js

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

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

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

Routes.test.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);
);

编辑

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

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 />/>

【讨论】:

我按照您的指示进行操作,但在 'const wrapper = shallow();' 行出现以下错误- 对象不是构造函数(评估 'Component(publicProps, publicContext, updateQueue)') 顺便说一句,我正在使用'react-router' @ZhaoYi 路由必须是 React 组件(参见 Routes.jsx) 这太棒了!它在 App.js 中工作: import Routes from "./Routes" export default class App extends Component render() return (
);在 index.js 中:从“react”导入 React;从“react-dom”导入 ReactDOM;从“./App”导入应用程序; ReactDOM.render( , document.getElementById('root') );
很好的答案,但请注意,因为它不处理直接使用render 而不是component 的情况:&lt;Route path="..." render=props =&gt; &lt;YourComponent ...props /&gt; /&gt;【参考方案2】:

我在另一个文件中为动态路由器定义了我的路径,所以我还在测试我渲染为 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;
);

【讨论】:

【参考方案3】:

只有在组件渲染成功时才会通过: 它适用于 Redux 和 react-router,包括 hooks。

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

【讨论】:

以上是关于如何用酶测试反应路由器的主要内容,如果未能解决你的问题,请参考以下文章

用开玩笑酶测试反应路由器 v4

如何使用新的反应路由器钩子测试组件?

如何用酶测试子组件方法?

如何用酶在ReactJS中添加窗口keydown事件的单元测试

如何用minicom配置路由器

如何用手机查看wifi网速