如何在Jest测试用例中Mock JSON.stringify并触发异常?
Jest测试覆盖catch代码块的正确姿势
你遇到的问题是直接赋值全局JSON.stringify为mock函数的方式不够严谨,且容易导致错误冒泡到测试代码中未被捕获。下面是正确的实现步骤和代码示例:
核心问题分析
直接修改JSON.stringify的赋值方式缺乏上下文隔离,若mock的抛出错误未被业务代码的try-catch包裹执行,就会直接触发测试报错。应该用Jest提供的jest.spyOn来安全mock全局方法,同时确保测试后恢复原始实现。
正确实现示例
假设你的业务代码在myModule.js中:
let myObject; const logError = (msg) => console.error(msg); function myMethod(obj) { try { myObject = { a: JSON.stringify(obj) }; } catch (err) { logError(`myMethod :::: ${err.message}`); } } module.exports = { myMethod, logError };
对应的测试文件myModule.test.js:
const { myMethod, logError } = require('./myModule'); // Mock logError以便后续断言调用情况 jest.mock('./myModule', () => { const original = jest.requireActual('./myModule'); return { ...original, logError: jest.fn() }; }); describe('myMethod', () => { // 每个测试后恢复所有mock,避免影响其他用例 afterEach(() => { jest.restoreAllMocks(); }); it('捕获JSON.stringify抛出的错误并调用logError', () => { // 用spyOn mock JSON.stringify,指定抛出错误 const stringifySpy = jest.spyOn(JSON, 'stringify') .mockImplementation(() => { throw new TypeError('Invalid JSON'); }); // 调用业务方法,触发try-catch逻辑 myMethod({}); // 断言logError被正确调用 expect(logError).toHaveBeenCalledWith('myMethod :::: Invalid JSON'); // 断言JSON.stringify确实被执行 expect(stringifySpy).toHaveBeenCalled(); }); });
额外说明
- 用
jest.spyOn替代直接赋值:既能mock方法行为,又能通过mockRestore()快速恢复原始实现,保证测试隔离性。 - 必须调用业务方法:只有触发包含try-catch的
myMethod,mock抛出的错误才会被业务代码捕获,进入catch块。 - Mock辅助函数:提前mock
logError可以方便断言错误处理逻辑是否正确执行。
内容的提问来源于stack exchange,提问作者APOORVA KALMANI
相关产品推荐
相关产品推荐

