Redux测试中如何mock useSelector返回的filePurpose以测试渲染逻辑
实现方案
你可以选以下两种常用方案实现,都能满足测试条件渲染的需求。
方案1:直接mock useSelector 方法
这个方案写法简单,不需要改动store状态,适合快速验证分支逻辑:
- 第一步:在测试文件顶部引入
useSelector,对react-redux做局部mock,保留其他API的真实实现,只替换useSelector为mock函数
import { render, screen } from '@testing-library/react'; import { useSelector, Provider } from 'react-redux'; import { BrowserRouter as Router } from 'react-router-dom'; import store from '../redux/store'; import { UploadErrors } from '../pages'; // mock react-redux,保留除useSelector外的其他真实导出 jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), useSelector: jest.fn() })); // 每个用例执行完清空mock,避免不同用例的mock值互相干扰 afterEach(() => { jest.clearAllMocks(); });
- 第二步:在具体测试用例中,给
useSelector设置你需要的返回值即可。比如要验证filePurpose === 'R'时显示test的分支:
test('The error message should be present', async () => { // 模拟useSelector返回的state.files字段值,和组件里解构的字段对应即可 useSelector.mockReturnValue({ fileErrors: [], fileMetaDataId: 'mock-id', filePurpose: 'R' // 这里设置你需要的测试值 }); render( <Provider store={store}> <Router> <UploadErrors /> </Router> </Provider> ); expect(screen.getByText('test')).toBeInTheDocument(); });
如果要验证另一个分支,只需要把filePurpose的值改成非'R'的内容,再断言页面存在not testing文本即可。
方案2:直接往测试store注入对应状态
这个方案不需要mock第三方库方法,更贴近Redux真实运行逻辑,项目用Redux Toolkit的话更推荐用这个方案:
你只需要在渲染组件前,往测试store里dispatch对应action,把files切片的状态改成你需要的测试值就行:
test('The error message should be present', async () => { // 提前往store注入测试状态,action type替换成你项目里修改files状态的对应type即可 store.dispatch({ type: 'files/setFileState', // 替换为你项目的真实action type payload: { fileErrors: [], fileMetaDataId: 'mock-id', filePurpose: 'R' } }); render( <Provider store={store}> <Router> <UploadErrors /> </Router> </Provider> ); expect(screen.getByText('test')).toBeInTheDocument(); });
小提示:如果用第二种方案,记得每个用例执行完重置store状态,避免不同用例的状态互相污染。
内容的提问来源于stack exchange,提问作者veena panakanapalli
相关产品推荐
相关产品推荐

