Jest中如何为beforeAll创建的Mock在单测中设置不同返回值?
Jest中为每个测试用例设置mock函数不同返回值的解决方案
你当前的问题核心是:在beforeAll中固定了shuffle的mock返回值,导致所有测试用例返回相同结果;尝试类型断言后调用mockReturnValue报错,是因为没有正确捕获到同一个mock函数实例。
以下是两种可行的解决方法:
方法一:提前定义全局mock实例(推荐)
将mock函数实例提前定义在文件顶部,利用Jest对jest.mock的提升特性,确保所有测试用例都能访问到同一个mock实例:
import { shuffle } from './random'; import { Foo } from './Foo'; // 提前创建可复用的mock函数实例 const mockShuffle = jest.fn() as jest.MockedFunction<typeof shuffle>; // 在文件顶部调用jest.mock,Jest会自动将其提升到最顶部执行 jest.mock('./random', () => ({ // 保留模块其他原有导出 ...jest.requireActual('./random'), // 用提前定义的mock实例替换shuffle shuffle: mockShuffle, })); describe('测试套件', () => { // 每个测试前重置mock,避免测试间的状态污染 beforeEach(() => { mockShuffle.mockReset(); }); test('返回3个Foo元素的数组', () => { mockShuffle.mockReturnValue([new Foo(), new Foo(), new Foo()]); // 执行你的业务逻辑,比如调用依赖shuffle的函数 // 编写断言验证结果 }); test('返回4个Foo元素的数组', () => { mockShuffle.mockReturnValue([new Foo(), new Foo(), new Foo(), new Foo()]); // 执行业务逻辑并断言 }); });
方法二:异步场景下的动态mock(适用于需要异步导入的情况)
如果必须在beforeAll中做异步操作,可以提前声明mock变量,确保外部能访问到同一个实例:
import { shuffle } from './random'; import { Foo } from './Foo'; // 提前声明mock变量,用于存储mock实例 let mockShuffle: jest.MockedFunction<typeof shuffle>; describe('测试套件', () => { beforeAll(async () => { // 创建mock函数实例 mockShuffle = jest.fn() as jest.MockedFunction<typeof shuffle>; jest.mock('./random', async () => { const actualModule = await jest.requireActual('./random'); return { ...actualModule, shuffle: mockShuffle, }; }); // 重新导入模块,确保mock生效 await import('./random'); }); beforeEach(() => { mockShuffle.mockReset(); }); test('返回3个Foo元素', () => { mockShuffle.mockReturnValue(Array(3).fill(new Foo())); // 测试逻辑 }); test('返回4个Foo元素', () => { mockShuffle.mockReturnValue(Array(4).fill(new Foo())); // 测试逻辑 }); });
报错原因说明
你之前的写法中,beforeAll里创建的shuffle mock是局部的jest.fn()实例,而外部的mockShuffle指向的是未被mock的原始shuffle函数,类型断言后并不是真正的Jest mock实例,因此调用mockReturnValue会报错。必须确保操作的是同一个mock函数实例才能修改返回值。
内容的提问来源于stack exchange,提问作者Forseti
相关产品推荐
相关产品推荐

