如何测试Jest中函数接收无效参数时直接返回的行为?
如何用Jest测试函数接收无效参数时直接返回的行为?
问题场景
我正在编写Jest测试套件,需要测试changeAge函数在接收无效参数时是否会直接返回。函数代码如下:
function changeAge (id, newAge) { const isWholeNumber = num => Number.isInteger(newAge) && newAge >= 0 if (!isWholeNumber(id) || !isWholeNumber(newAge)) { return } const person = getPerson(id) person.age = newAge }
问题在于,我无法在测试中直接获取person数据来验证年龄是否被修改,该如何测试无效参数下的直接返回行为?
解决方案
核心思路是监控依赖函数getPerson的调用情况:如果参数无效,changeAge会提前return,不会执行到getPerson(id)这一行。所以只要验证getPerson从未被调用,就能证明函数确实提前返回了。
步骤1:Mock依赖函数
首先用Jest mock掉getPerson,不需要它的实际逻辑,只需要跟踪它的调用状态:
// 假设getPerson和changeAge在同一个文件your-module.js中 jest.mock('./your-module', () => ({ getPerson: jest.fn() })); const { getPerson, changeAge } = require('./your-module');
步骤2:编写测试用例
针对各种无效参数场景,验证changeAge直接返回,且getPerson未被调用:
describe('changeAge', () => { // 每次测试前重置mock调用记录,避免用例间污染 beforeEach(() => { getPerson.mockClear(); }); // 测试id为负数的情况 test('id为负数时直接返回,不调用getPerson', () => { const result = changeAge(-1, 20); expect(result).toBeUndefined(); expect(getPerson).not.toHaveBeenCalled(); }); // 测试id为小数的情况 test('id为非整数时直接返回,不调用getPerson', () => { const result = changeAge(1.5, 20); expect(result).toBeUndefined(); expect(getPerson).not.toHaveBeenCalled(); }); // 测试newAge为负数的情况 test('newAge为负数时直接返回,不调用getPerson', () => { const result = changeAge(1, -5); expect(result).toBeUndefined(); expect(getPerson).not.toHaveBeenCalled(); }); // 测试newAge为非数字的情况 test('newAge为字符串时直接返回,不调用getPerson', () => { const result = changeAge(1, '20'); expect(result).toBeUndefined(); expect(getPerson).not.toHaveBeenCalled(); }); // 可选:添加有效参数的对比测试 test('参数有效时调用getPerson并修改年龄', () => { const mockPerson = { age: 18 }; getPerson.mockReturnValue(mockPerson); changeAge(1, 20); expect(getPerson).toHaveBeenCalledWith(1); expect(mockPerson.age).toBe(20); }); });
注意:修复原函数的bug
原函数中的isWholeNumber存在逻辑错误:它始终判断的是newAge,而非传入的参数num,这会导致isWholeNumber(id)的判断完全失效。需要修正为:
const isWholeNumber = num => Number.isInteger(num) && num >= 0
否则测试用例可能会出现不符合预期的结果。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

