Jest测试用例异常:第二个测试返回id 2导致断言失败
解决Jest测试用例因共享数组修改导致的失败问题
问题分析
你遇到的核心问题是两个测试用例共享了同一个mockData数组:第一个测试执行时,Helpers.execute()调用data.shift()直接修改了原数组(移除了第一个元素);第二个测试运行时,mockData已经变成[{id:2}, {id:3}],所以返回的id自然是2,不符合预期。另外注意原Helpers.js中调用异步函数getData()时漏加了await,会导致data是Promise对象,调用shift()会报错,这个问题也需要同步修复。
修复方案
方案1:Mock时返回数组副本
每次mockgetData时,返回mockData的新副本,确保每个测试用例拿到独立的数组,不会互相影响:
// Helpers.spec.js describe('Helpers', () => { beforeAll(() => { jest.clearAllMocks(); jest.mock('./operations', () => ({ Operators: jest.fn() })); }); afterEach(() => { jest.clearAllMocks(); }); const mockData = [ { id: 1 }, { id: 2 }, { id: 3 } ]; it('Should return a id 1', async () => { // 用扩展运算符创建数组副本 Operations.getData = jest.fn().mockResolvedValue([...mockData]); const response = await Helpers.execute(); expect(response.id).toBe(1); }); it('Should return a id 1 with true flag', async () => { Operations.getData = jest.fn().mockResolvedValue([...mockData]); Operations.track = jest.fn().mockResolvedValue({}); const response = await Helpers.execute(true); expect(response.id).toBe(1); }); });
方案2:在beforeEach中初始化mockData
把mockData的定义移到beforeEach钩子中,每个测试用例执行前都会重新创建全新的数组:
// Helpers.spec.js describe('Helpers', () => { let mockData; beforeAll(() => { jest.clearAllMocks(); jest.mock('./operations', () => ({ Operators: jest.fn() })); }); beforeEach(() => { // 每个测试前重置数组 mockData = [ { id: 1 }, { id: 2 }, { id: 3 } ]; jest.clearAllMocks(); }); it('Should return a id 1', async () => { Operations.getData = jest.fn().mockResolvedValue(mockData); const response = await Helpers.execute(); expect(response.id).toBe(1); }); it('Should return a id 1 with true flag', async () => { Operations.getData = jest.fn().mockResolvedValue(mockData); Operations.track = jest.fn().mockResolvedValue({}); const response = await Helpers.execute(true); expect(response.id).toBe(1); }); });
方案3:修改业务逻辑避免修改原数组(可选)
如果业务场景允许,不直接修改getData返回的数组,而是返回第一个元素的副本,同时补上await修复异步调用问题:
// Helpers.js import { getData, track } from './operations'; export class Helpers { static async execute(request) { if(request) track(); const data = await getData(); // 补上await获取实际数组 // 返回第一个元素,而非修改原数组 return { ...data[0] }; } }
内容的提问来源于stack exchange,提问作者Jay Bhajiyawala
相关产品推荐
相关产品推荐

