如何用Jest模拟自定义React Hook中使用的模块(规避提升问题)
解决不同测试中模拟useFormContext返回不同isValid值的问题
你可以通过全局mock react-hook-form并在每个测试中重置mock返回值的方式实现需求,具体步骤如下:
1. 全局mock react-hook-form
在测试文件顶部,用jest.mock将useFormContext替换为一个可控制的jest模拟函数:
jest.mock('react-hook-form', () => ({ useFormContext: jest.fn(), }));
2. 测试前重置mock状态
在beforeEach钩子中清除所有mock的调用记录和返回值,避免测试间的状态污染:
import { renderHook } from '@testing-library/react-hooks'; import { useFormContext } from 'react-hook-form'; import { useCustomHook } from './useCustomHook'; describe('useCustomHook', () => { beforeEach(() => { jest.clearAllMocks(); }); // 测试用例... });
3. 为每个测试单独设置mock返回值
在每个测试用例中,通过mockReturnValue为useFormContext设置对应isValid状态的返回值,再渲染钩子进行测试:
测试isValid为true的场景
test('functionThatUsesIsValid behaves correctly when isValid is true', () => { // 设置mock返回值 useFormContext.mockReturnValue({ formState: { isValid: true }, }); const { result } = renderHook(() => useCustomHook()); // 调用目标函数并执行断言 result.current.functionThatUsesIsValid(); // 这里添加你的断言逻辑,例如验证函数执行后的结果或副作用 });
测试isValid为false的场景
test('functionThatUsesIsValid behaves correctly when isValid is false', () => { // 设置另一个mock返回值 useFormContext.mockReturnValue({ formState: { isValid: false }, }); const { result } = renderHook(() => useCustomHook()); result.current.functionThatUsesIsValid(); // 对应的断言逻辑 });
为什么这种方式有效?
- 全局
jest.mock会在测试启动时就替换掉真实的useFormContext,避免调用真实实现。 jest.clearAllMocks()确保每个测试的mock状态都是干净的,不会被之前的测试影响。- 每个测试单独设置
mockReturnValue,可以精准控制isValid的取值,实现不同场景的测试。
内容的提问来源于stack exchange,提问作者Ross
相关产品推荐
相关产品推荐

