mock useSelector of react-redux with jest for test with reac



我正在尝试测试一个使用react redux进行状态管理的组件。

为了快速测试,我想模拟useSelector,如下所示:

const templates = [
{
id: ...,
name: ...,
...
},
{
id: ...,
name: ...,
...
},
]

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
}));

describe('some awesome description', () => {
beforeEach(() => {
useSelector.mockImplementation(callback => callback(templates));
});
});

但在运行测试时,失败如下:

TypeError: Cannot read properties of undefined (reading 'ids')
141 | describe('layouts/TemplatesPanel', () => {
142 |   beforeEach(() => {
> 143 |     useSelector.mockImplementation(callback => callback(templates));
|                                                ^

最好不要mockuseSelector,mock实现可能会破坏它的函数,因为它的函数不仅仅是返回某个状态切片。请参阅useSelector的实际实现,它不仅仅返回selectedState

推荐的方法是创建一个模拟存储并为其提供模拟数据

例如

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' } });
});
});

测试结果:

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

当我们稍后调度一个操作时,useSelector钩子将订阅存储的更改,它将再次执行并获得更新的状态切片。如果您模拟它,只返回一个状态切片,则此功能将不再工作。

相关内容

  • 没有找到相关文章