如何为React中useEffect钩子内的if条件语句编写单元测试用例
useEffect条件分支测试实现方案
我们使用React Testing Library + Jest 完成测试,核心逻辑是mock redux的useSelector、useDispatch两个钩子,分别覆盖if条件成立、不成立两种场景。
测试前置准备
先完成依赖mock和基础引入:
import { render } from '@testing-library/react'; import { useDispatch, useSelector } from 'react-redux'; import Greet from './Greet'; // 替换为你实际存放getDetails action的文件路径 import { getDetails } from '@/store/actions'; // 全局mock react-redux提供的钩子 jest.mock('react-redux', () => ({ useDispatch: jest.fn(), useSelector: jest.fn(), })); // 模拟getDetails action,避免触发真实接口请求 jest.mock('@/store/actions', () => ({ getDetails: jest.fn(), }));
测试用例1:命中if条件(两个数组都为空)
验证组件挂载后会调用dispatch(getDetails()):
test('state和country数据都为空时,触发getDetails dispatch', () => { const mockDispatch = jest.fn(); useDispatch.mockReturnValue(mockDispatch); // 模拟redux返回两个空数组,命中判断条件 useSelector.mockImplementation((selector) => selector({ stateDatalist: [], CountryDatalist: [] }) ); render(<Greet />); // 断言dispatch调用符合预期 expect(mockDispatch).toHaveBeenCalledWith(getDetails()); expect(getDetails).toHaveBeenCalledTimes(1); });
测试用例2:不命中if条件(至少一个数组不为空)
验证组件挂载后不会触发对应dispatch:
test('任一数据不为空时,不触发getDetails dispatch', () => { const mockDispatch = jest.fn(); useDispatch.mockReturnValue(mockDispatch); // 模拟stateDatalist有值,不命中判断条件 useSelector.mockImplementation((selector) => selector({ stateDatalist: [{ id: 1, name: '广东省' }], CountryDatalist: [] }) ); render(<Greet />); // 断言dispatch未触发 expect(mockDispatch).not.toHaveBeenCalledWith(getDetails()); expect(getDetails).toHaveBeenCalledTimes(0); });
补充说明
你当前组件的useEffect依赖是空数组,只会在组件首次挂载时执行一次,无需额外测试更新场景;如果后续调整了useEffect的依赖项,需要对应补充依赖变更后的测试逻辑。如果getDetails是异步thunk类型的action,上述测试逻辑依然适用,无需调整。
内容的提问来源于stack exchange,提问作者Pavan Kalyan Payyavula
相关产品推荐
相关产品推荐

