如何测试依赖外部变量的函数?Jest单元测试求助
Jest测试依赖外部变量的函数的正确方法
问题分析
你的测试失败有两个核心原因:
greetings函数依赖全局变量count,测试时无法精准控制这个变量的值,导致输出不可预测- 测试代码中使用
||连接字符串传入toBe,这是错误语法——JavaScript 里||会返回第一个真值字符串,你的测试实际只在判断函数返回等于第一个字符串,完全没覆盖另外两种情况
第一步:重构原函数(关键)
依赖全局变量的函数天生难测试,先把count改成函数参数,让函数输出完全由输入决定:
function greetings(count){ // 新增count参数 if(count === 0){ return "Hello! I am here to assist you in picking your ideal Apple product! YAYYY :D! We can start off by selecting the type of Apple product you wish to buy"; }else if(count === 1){ return "Hello again! Once we get your budget I can narrow down options for your ideal product! Whats your max budget?"; }else if(count === 2){ return "Hello again my friend! Once we get your ideal device size I can narrow down options for your ideal product! Whats your ideal size for this device?"; } }
这里把==换成===是更严谨的全等判断,避免隐式类型转换的坑。
第二步:正确的测试写法
写法1:拆分单独测试用例
每个count值对应一个独立测试,清晰明了:
// 测试count=0的情况 test('greetings returns welcome message when count is 0', () => { expect(greetings(0)).toBe("Hello! I am here to assist you in picking your ideal Apple product! YAYYY :D! We can start off by selecting the type of Apple product you wish to buy"); }); // 测试count=1的情况 test('greetings returns budget prompt when count is 1', () => { expect(greetings(1)).toBe("Hello again! Once we get your budget I can narrow down options for your ideal product! Whats your max budget?"); }); // 测试count=2的情况 test('greetings returns size prompt when count is 2', () => { expect(greetings(2)).toBe("Hello again my friend! Once we get your ideal device size I can narrow down options for your ideal product! Whats your ideal size for this device?"); });
写法2:用test.each批量测试(更简洁)
如果用例很多,用test.each可以减少重复代码:
test.each([ [0, "Hello! I am here to assist you in picking your ideal Apple product! YAYYY :D! We can start off by selecting the type of Apple product you wish to buy"], [1, "Hello again! Once we get your budget I can narrow down options for your ideal product! Whats your max budget?"], [2, "Hello again my friend! Once we get your ideal device size I can narrow down options for your ideal product! Whats your ideal size for this device?"] ])('greetings returns correct message when count is %i', (count, expected) => { expect(greetings(count)).toBe(expected); });
如果必须保留全局变量(不推荐)
如果因为某些原因不能修改原函数,测试时需要手动控制全局count的值,注意要在测试前后重置变量,避免用例互相影响:
let count; // 声明全局变量(模拟你的环境) function greetings(){ if(count == 0){ return "Hello! I am here to assist you in picking your ideal Apple product! YAYYY :D! We can start off by selecting the type of Apple product you wish to buy"; }else if(count == 1){ return "Hello again! Once we get your budget I can narrow down options for your ideal product! Whats your max budget?"; }else if(count == 2){ return "Hello again my friend! Once we get your ideal device size I can narrow down options for your ideal product! Whats your ideal size for this device?"; } } // 测试代码 test('greetings returns correct message for count=0', () => { count = 0; expect(greetings()).toBe("Hello! I am here to assist you in picking your ideal Apple product! YAYYY :D! We can start off by selecting the type of Apple product you wish to buy"); }); test('greetings returns correct message for count=1', () => { count = 1; expect(greetings()).toBe("Hello again! Once we get your budget I can narrow down options for your ideal product! Whats your max budget?"); }); // 可选:用beforeEach重置count,避免用例污染 beforeEach(() => { count = undefined; });
这种方法不推荐,因为全局变量容易导致测试用例互相干扰,维护成本高。
内容的提问来源于stack exchange,提问作者xIssa
相关产品推荐
相关产品推荐

