I have created simple react component and write test cases of components that are working correctly. I have got coverage report for the test cases.
Now, I have added react redux in my other component. this component contains componentDidMount() and export default connect(null, updateProps)(ComponentName) methods. I need to write unit test cases for these methods.
Please refer to the below code sample,
class MyComponent extends Component {
componentDidMount = () => {
//some code here
)
handleSignIn = (e) => {
//some code here
}
render() {
return (
<div>
<form onSubmit={this.handleSignIn}>
<Input
type="text"
name="inputText"
placeholder="Text"
autoFocus
required
/>
</form>
</div>
);
}
const updateProps = (dispatch) => {
return {
//some code here
};
};
export default connect(null, updateProps)(MyComponent);
CodePudding user response:
In your code you have two things:
class MyComponent
and
const thisIsBasicallyAnotherComponent = connect(null, updateProps)(MyComponent);
So if you want to test your component you basically have two options. You can test your component wrapped and connected to the redux store or you can write a simple unit test for your class component as it is.
What I would recommend doing is to export your class component
- class MyComponent extends Component { // replace this
export class MyComponent extends Component { // with this
And then you can test your React component with Jest like any other component.
test('Link changes the class when hovered', () => {
const component = renderer.create(
<MyComponent {...mockProps} /> // !! keep in mind that you have to manually pass what you have in `updateProps` because the component is not connected to Redux store anymore
);
// ... write your test and expectations here
});
Otherwise, you can test your connected component (what is exported by default) but then you would have to wrap the component in Redux provider in order to test it.
You can find more information about testing here:
CodePudding user response:
You can use Provider
from react-redux
or redux-mock-store
to avoid need to use real reducer:
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import MyComponent from './MyComponent.jsx';
const mockStore = configureStore([thunk]);
it('does something on mount', () => {
// let's mock some Redux state
const store = mockStore({ slice1: { id: 2, name: '11' } });
mount(<Provider store={store}><MyComponent /></Provider>);
expect(store.getActions()).toContainEqual({
type: 'some-type',
payload: ....
});
});
But this is that easy only to simple actions. What if you use redux-thunk
and there is some loading? There are 2 ways:
- Pass
redux-thunk
middleware tomockStore
and mock network, say, by usingmock-fetch
ornock
. Easier to set up, but also it might be overkill if you already test your Redux directly, repeating tests for "loading failed", "loading takes long" etc also to your component would mean double work. - You can mock
../yourPath/actions.js
so every action there would be plain object, not a thunk. I typically go this way.
But what about "exporting unwrapped component so we could test component in isolation, without Redux"? You see, it was working when connect
was the only possible API. But now with hooks like useSelector
, useDispatch
, useStore
in mind, it's way more reliable to make tests for "my component IN Redux" first. Otherwise with "double exports" approach we may find out than converting component from class to function means way more work on patching tests, not on component itself.