如何复用Jest.mock()代码?CRA-rewired React项目测试困境
复用Jest Mock代码的可行方案
首先得明确:你之前用工具函数封装jest.mock无效的原因是——Jest会在执行测试代码前静态扫描所有文件中的jest.mock调用,工具函数里的jest.mock是运行时才执行的,这时候Jest的预扫描已经完成,所以不会生效。
下面是两种可行的复用方式:
方式一:集中式Mock文件(最推荐)
把所有需要复用的jest.mock调用放到一个单独的文件里,然后在需要的测试文件顶层导入该文件即可:
- 创建一个共享Mock文件
比如在src/test-utils/shared-mocks.ts中写入所有重复的mock:
// 这里放所有需要复用的jest.mock配置 jest.mock('module-name-A', () => ({ default: jest.fn(() => 'mock-data-A'), someExport: jest.fn(), })); jest.mock('module-name-B', () => ({ // 你的mock实现 })); // 继续添加其他需要复用的mock...
- 在需要的测试文件中导入
确保在文件最顶层(describe块之外、其他导入之前)导入这个文件,保证Jest能提前扫描到里面的mock:
// 必须放在最顶部,优先于组件和测试工具的导入 import '../test-utils/shared-mocks'; import { render } from '@testing-library/react'; import TargetComponent from './TargetComponent'; describe('TargetComponent', () => { test('renders correctly', () => { render(<TargetComponent />); // 测试逻辑 }); });
方式二:自定义Mock目录+简化调用
如果你的mock逻辑比较固定,可以利用Jest的默认mock目录机制:
- 在项目根目录创建
__mocks__文件夹,然后为每个需要mock的模块创建对应的mock文件,比如__mocks__/module-name-A.ts:
// 这里写module-name-A的mock实现 export default jest.fn(() => 'mock-data-A'); export const someExport = jest.fn();
- 在需要的测试文件中只需要写一行简化的mock调用:
// 只需要这一行,Jest会自动加载__mocks__下的对应文件 jest.mock('module-name-A'); jest.mock('module-name-B'); // 后续测试代码...
这种方式适合单个mock需要在多处复用,但不同测试文件可能需要不同mock的场景,相比方式一灵活度更高,但还是需要在每个测试文件写少量代码。
注意事项
- 确保共享mock文件的导入位置在测试文件最顶层,避免Jest扫描不到
- 如果需要保留原模块的部分类型或实现,可以用
jest.requireActual来混合mock:jest.mock('module-name', () => ({ ...jest.requireActual('module-name'), // 覆盖需要mock的部分 someMethod: jest.fn(), }));
内容的提问来源于stack exchange,提问作者zaitsman
相关产品推荐
相关产品推荐

