Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test React Router params with Redux and enzyme

This has been resolved

I have a component that is wrapped with connect() and withRouter. To render itself, it uses routing information in this.props.match.params. In my Enzyme test, the match prop that I pass to the WrappedComponent does not seem to propagate when I log the props. However, if I add additional props (under a different key besides match), they propagate fine.

The following test replicates my issue. I am fairly new to React so if anyone has tips on what I am doing wrong and what I can do to debug this, it would be greatly appreciated.

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { mount } from 'enzyme';
import configureStore from 'redux-mock-store';
import { MemoryRouter, withRouter } from 'react-router-dom';
import { Provider, connect } from 'react-redux';


class TestComponent extends Component {
  constructor(props) {
    super(props);
    console.log(props);
  }

  render() {
    const { params } = this.props.match;
    return (
      <div>
        { params.var1 }
      </div>
    );
  }
}

TestComponent.propTypes = {
  match: PropTypes.shape({
    params: PropTypes.shape({
      var1: PropTypes.string.isRequired,
    }),
  }).isRequired,
};

const WrappedComponent = withRouter(connect()(TestComponent));

describe('WrappedComponent', () => {
  const mockStore = configureStore();
  const initialState = {};
  let store;
  let wrapper;

  beforeEach(() => {
    store = mockStore(initialState);

    const props = {
      match: {
        params: {
          roomType: 'public',
          roomName: 'test',
        },
      },
    };

    wrapper = mount(
      <Provider store={store}>
        <MemoryRouter>
          <WrappedComponent {...props} />
        </MemoryRouter>
      </Provider>,
    );
  });

  it('renders without crashing', () => {
    expect(wrapper).toHaveLength(1);
  });
});

When I run the test, match.params is {}.

console.error node_modules/react/node_modules/fbjs/lib/warning.js:33
Warning: Failed prop type: The prop `match.params.roomType` is marked as required in `TestComponent`, but its value is `undefined`.
    in TestComponent (created by Connect(TestComponent))
    in Connect(TestComponent) (created by Route)
    in Route (created by withRouter(Connect(TestComponent)))
    in withRouter(Connect(TestComponent)) (at TestComponent.js:56)
    in Router (created by MemoryRouter)
    in MemoryRouter (at TestComponent.js:55)
    in Provider (created by WrapperComponent)
    in WrapperComponent

console.log src/components/__tests__/TestComponent.js:11
{ match: { path: '/', url: '/', params: {}, isExact: true },
  location:
   { pathname: '/',
     search: '',
     hash: '',
     state: undefined,
     key: '5gc3i1' },
  history:
   { length: 1,
     action: 'POP',
     location:
      { pathname: '/',
        search: '',
        hash: '',
        state: undefined,
        key: '5gc3i1' },
     index: 0,
     entries: [ [Object] ],
     createHref: [Function: createPath],
     push: [Function: push],
     replace: [Function: replace],
     go: [Function: go],
     goBack: [Function: goBack],
     goForward: [Function: goForward],
     canGo: [Function: canGo],
     block: [Function: block],
     listen: [Function: listen] },
  staticContext: undefined,
  dispatch: [Function: dispatch] }

Edit: I've gotten the test to pass by modifying it to use this:

wrapper = mount(
  <Provider store={store}>
    <MemoryRouter initialEntries={['/param1val/param2val']}>
      <Switch>
        <Route path="/:param1/:param2" component={WrappedTestComponent} />
      </Switch>
    </MemoryRouter>
  </Provider>,
);

I'll keep this open question open in case there is a recommended way to do this without the Switch and Route.

like image 330
Nosajool Avatar asked Oct 30 '17 22:10

Nosajool


1 Answers

Slawa's answer is what I ended up doing. It is not useful to test the functionality of React Router and Redux. Exporting the plain React component made the test much simpler.

like image 110
Nosajool Avatar answered Nov 15 '22 04:11

Nosajool