You'd better not mock useSelector
, mock implementation possibly breaks its function because its function is not only to return a certain state slice. See the useSelector
real implementation, it doesn't just return the selectedState
.
The recommended way is to create a mock store and provide mock data for it.
E.g.
index.tsx
:
import React from 'react';
import { useSelector } from 'react-redux';
export type Template = {
id: string;
name: string;
};
export type RootState = {
templates: Template[];
};
export const MyComp = () => {
const templates = useSelector<RootState>((state) => state.templates);
console.log('templates: ', templates);
return <div>MyComp</div>;
};
index.test.tsx
:
import { render } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { MyComp, RootState, Template } from '.';
describe('73494842', () => {
test('should pass', () => {
const templates: Template[] = [
{ id: '1', name: 'a' },
{ id: '2', name: 'b' },
];
const mockStore = createStore<RootState, any, any, any>((state = { templates }, action) => {
if (action.type === 'UPATE_NAME') {
return {
...state,
templates: templates.map((t) => (t.id === action.payload.id ? { ...t, name: action.payload.name } : t)),
};
}
return state;
});
render(
<Provider store={mockStore}>
<MyComp />
</Provider>
);
mockStore.dispatch({ type: 'UPATE_NAME', payload: { id: '1', name: 'c' } });
});
});
Test result:
73494842
✓ should pass (44 ms)
console.log
templates: [ { id: '1', name: 'a' }, { id: '2', name: 'b' } ]
at MyComp (stackoverflow/73494842/index.tsx:14:11)
console.log
templates: [ { id: '1', name: 'c' }, { id: '2', name: 'b' } ]
at MyComp (stackoverflow/73494842/index.tsx:14:11)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.931 s, estimated 11 s
When we dispatch an action later, the useSelector
hook will subscribe to the changes of the store, it will execute again and get the updated state slice. If you mock it just return a state slice, this feature is not working anymore.