How to test react-router with enzyme

后端 未结 3 1220
时光说笑
时光说笑 2020-12-05 13:47

I am using enzyme+mocha+chai to test my react-redux project. Enzyme provides shallow to test component behavior. But I didn\'t find a way to test the router. I am using reac

相关标签:
3条回答
  • 2020-12-05 14:22

    This will only pass if the component is rendered successfully: It works with Redux and react-router including 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);
      });
    });
    
    0 讨论(0)
  • 2020-12-05 14:31

    You can wrap your router inside a component in order to test it.

    Routes.jsx

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

    index.js

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

    Then you have to shallow render your Routes component, and you are able to create an object map to check the correspondance between path and related component.

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

    EDIT

    In case you want to additionally handle the case of render 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;
    }, {});
    

    It will work only in case you render directly the component you want to test (without extra wrapper).

    <Route path="nurse/authorization" render{() => <NurseAuthorization />}/>
    
    0 讨论(0)
  • 2020-12-05 14:35

    I had my paths defined in another file for the dynamic router, so I am also testing that all the routes I am rendering as Routes are defined in my paths.js constants:

    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;
    });
    
    0 讨论(0)
提交回复
热议问题