如何在Jest中通过提取函数或it.each减少测试代码重复?
减少Jest测试重复代码的两种方案
你的场景既可以用提取辅助函数,也可以用it.each批量生成测试用例,两种方案分别如下:
方案一:提取重复断言到辅助函数
把重复的两个断言封装成复用函数,在每个测试用例的错误捕获逻辑中调用即可:
// 定义辅助函数,复用重复断言逻辑 const validateErrorAndFetchNotCalled = (e: Error) => { expect(<jest.Mock>fetch).not.toHaveBeenCalled(); expect(e).toBeInstanceOf(TypeError); }; // 修改后的测试用例 it('should throw if no args were passed', async () => { expect.assertions(3); return readPricing().catch((e: Error) => { validateErrorAndFetchNotCalled(e); expect(e.message).toBe( `The 'products' information is required to successfully be able to execute this request.` ); }); }); it('should throw if no product IDs were passed', () => { expect.assertions(3); const noIdData = { products: [{ salesPrice: '60.00' }, { salesPrice: '80.00' }], }; // @ts-expect-error return readPricing(noIdData).catch((e: Error) => { validateErrorAndFetchNotCalled(e); expect(e.message).toBe(`The 'productId' is required to successfully be able to execute this request.`); }); }); it('should throw if an empty array of products was passed', () => { expect.assertions(3); const noIdData = { products: [] }; return readPricing(noIdData).catch((e: Error) => { validateErrorAndFetchNotCalled(e); expect(e.message).toBe( `The 'products' information is required to successfully be able to execute this request.` ); }); });
方案二:使用it.each批量生成测试用例
把测试的核心参数(测试描述、输入数据、预期错误消息)整理成数组,通过it.each遍历生成所有测试用例,彻底消除重复的测试结构:
// 定义测试参数数组:[测试描述, 输入数据, 预期错误消息] const errorTestCases = [ [ 'no args were passed', undefined, `The 'products' information is required to successfully be able to execute this request.` ], [ 'no product IDs were passed', { products: [{ salesPrice: '60.00' }, { salesPrice: '80.00' }] }, `The 'productId' is required to successfully be able to execute this request.` ], [ 'an empty array of products was passed', { products: [] }, `The 'products' information is required to successfully be able to execute this request.` ] ]; // 使用it.each批量生成测试 it.each(errorTestCases)('should throw if %s', async (_, inputData, expectedMessage) => { expect.assertions(3); // @ts-expect-error 处理无参数或参数不符合类型的情况 return readPricing(inputData).catch((e: Error) => { expect(<jest.Mock>fetch).not.toHaveBeenCalled(); expect(e).toBeInstanceOf(TypeError); expect(e.message).toBe(expectedMessage); }); });
两种方案各有优势:
- 辅助函数适合保留原有测试结构,只消除重复断言的场景;
it.each适合测试逻辑高度一致的场景,能大幅减少冗余代码。
内容的提问来源于stack exchange,提问作者Kristina
相关产品推荐
相关产品推荐

