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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With