How to Unit Test React-Redux Connected Components?
The problem with the accepted answer is that we are exporting something unnecessarily just to be able to test it. And exporting a class just to test it is not a good idea in my opinion.
Here is a neater solution without the need of exporting anything but the connected component:
If you are using jest, you can mock connect
method to return three things:
- mapStateToProps
- mapDispatchToProps
- ReactComponent
Doing so is pretty simple. There are 2 ways: Inline mocks or global mocks.
1. Using inline mock
Add the following snippet before the test's describe function.
jest.mock('react-redux', () => {
return {
connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
mapStateToProps,
mapDispatchToProps,
ReactComponent
}),
Provider: ({ children }) => children
}
})
2. Using file mock
- Create a file
__mocks__/react-redux.js
in the root (where package.json is located) - Add the following snippet in the file.
module.exports = {
connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
mapStateToProps,
mapDispatchToProps,
ReactComponent,
}),
Provider: ({children}) => children
};
After mocking, you would be able to access all the above three using Container.mapStateToProps
,Container.mapDispatchToProps
and Container.ReactComponent
.
Container can be imported by simply doing
import Container from '<path>/<fileName>.container.js'
Hope it helps.
Note that if you use file mock. The mocked file will be used globally for all the test cases(unless you do jest.unmock('react-redux'))
before the test case.
Edit: I have written a detailed blog explaining the above in detail:
http://rahulgaba.com/front-end/2018/10/19/unit-testing-redux-containers-the-better-way-using-jest.html
A prettier way to do this, is to export both your plain component, and the component wrapped in connect. The named export would be the component, the default is the wrapped component:
export class Sample extends Component {
render() {
let { verification } = this.props;
return (
<h3>This is my awesome component.</h3>
);
}
}
const select = (state) => {
return {
verification: state.verification
}
}
export default connect(select)(Sample);
In this way you can import normally in your app, but when it comes to testing you can import your named export using import { Sample } from 'component'
.