如何使用Jest和Enzyme为使用useReducer Hook的组件编写单元测试
组件单元测试实现方案
核心测试原则
优先测试组件的对外表现行为,不耦合内部实现细节,无需专门断言useReducer的调用、内部state的取值,只要组件渲染结果符合预期即可。后续你如果把useReducer替换成useState等其他状态管理逻辑,测试用例不需要修改。
依赖说明
采用React官方推荐的@testing-library/react作为测试工具,配合Jest运行即可,无需额外依赖。
完整测试代码示例
假设你的组件文件为Func.js,Loader组件和它同目录,测试代码写在Func.test.js中:
import { render, screen, waitFor } from '@testing-library/react'; import Func from './Func'; // Mock自定义Loader组件,添加testId方便断言渲染状态 jest.mock('./Loader', () => () => <div data-testid="loader" />); // 用例1:覆盖初始状态渲染分支 test('初始状态下loading为false,渲染空name内容', () => { render(<Func />); // 断言Loader未渲染 expect(screen.queryByTestId('loader')).not.toBeInTheDocument(); // 断言name对应div内容为空 expect(screen.getByText('')).toBeInTheDocument(); }); // 用例2:覆盖加载状态、数据返回后的渲染分支 // 注:以下示例假设你的实际组件会在挂载后请求接口,请求过程中loading为true // 你可以根据自己的业务逻辑调整触发状态变更的方式 test('状态更新后渲染结果符合预期', async () => { // 模拟异步接口请求 jest.spyOn(global, 'fetch').mockResolvedValueOnce({ json: async () => ({ name: '测试用户' }) }); render(<Func />); // 断言加载中状态下Loader正常渲染 expect(await screen.findByTestId('loader')).toBeInTheDocument(); // 等待请求完成后断言Loader消失 await waitFor(() => { expect(screen.queryByTestId('loader')).not.toBeInTheDocument(); }); // 断言接口返回的name值正常渲染 expect(screen.getByText('测试用户')).toBeInTheDocument(); });
注意事项
- 如果你的
reducer逻辑非常复杂,可以单独把reducer函数抽离出组件文件,单独针对reducer编写单元测试,传入不同的state和action,断言返回的新state是否符合预期即可 - 不要使用直接读取组件内部state、shallow渲染等耦合实现的测试写法,这类测试维护成本极高,只要修改组件内部逻辑就会失效,没有实际意义。
内容的提问来源于stack exchange,提问作者sky blue
相关产品推荐
相关产品推荐

