如何用Karma+Jasmine测试Angular 2中的局部变量?
如何用Jasmine测试函数中的局部变量
嗨,我来帮你搞定这个问题~首先得明确一点:局部变量(比如你代码里的isSpecial)是函数内部的私有变量,外部代码(包括你的测试用例)根本没法直接访问它,所以直接测试它的值是行不通的。不过我们可以通过测试它带来的「行为结果」,或者重构代码让逻辑更易测试,来达到目的。
先提个小细节:你代码里写的if(isSpeciality)应该是if(isSpecial)的笔误吧?这个得先修正,不然逻辑会出错哦。
下面给你两种实用的解决方案:
方案1:测试局部变量带来的行为(无需重构原有代码)
你的isSpecial变量最终决定了是否调用另一个函数,那我们可以通过测试这个「目标函数是否被调用」来间接验证isSpecial的取值是否符合预期。
用Jasmine的spyOn监听目标函数,然后断言它的调用情况即可:
describe('checkDayIsOpen function', () => { let yourInstance; // 替换成你的类/组件实例 beforeEach(() => { yourInstance = new YourClass(); // 初始化你的实例 }); it('should trigger the target function when any item is open', () => { // 设置测试数据:存在开放状态的item yourInstance.items = [{ is_open: true }, { is_open: false }]; // 监听要调用的那个函数 spyOn(yourInstance, 'anotherFunction'); // 替换成实际的函数名 // 执行待测试函数 yourInstance.checkDayIsOpen(); // 断言函数被调用,说明isSpecial为true expect(yourInstance.anotherFunction).toHaveBeenCalled(); }); it('should NOT trigger the target function when no items are open', () => { // 设置测试数据:所有item都不开放 yourInstance.items = [{ is_open: false }, { is_open: false }]; spyOn(yourInstance, 'anotherFunction'); yourInstance.checkDayIsOpen(); // 断言函数未被调用,说明isSpecial为false expect(yourInstance.anotherFunction).not.toHaveBeenCalled(); }); });
方案2:重构代码,把逻辑抽成可测试的公共函数
如果希望更直接地测试「是否有开放项」这个核心逻辑,可以把判断逻辑从checkDayIsOpen里抽出来,变成一个单独的公共方法,这样就能直接测试这个方法的返回值(也就是原来的isSpecial)。
重构后的代码:
checkDayIsOpen(): void { const isSpecial = this.hasOpenItems(); if (isSpecial) { this.anotherFunction(); // 替换成你的实际函数 } } // 新增公共方法,专门判断是否有开放的item hasOpenItems(): boolean { // 用some方法替代forEach,逻辑更简洁高效 return this.items.some(item => item.is_open); }
然后测试这个新的hasOpenItems函数:
describe('hasOpenItems function', () => { let yourInstance; beforeEach(() => { yourInstance = new YourClass(); }); it('should return true when any item is open', () => { yourInstance.items = [{ is_open: true }, { is_open: false }]; expect(yourInstance.hasOpenItems()).toBe(true); }); it('should return false when no items are open', () => { yourInstance.items = [{ is_open: false }, { is_open: false }]; expect(yourInstance.hasOpenItems()).toBe(false); }); });
为什么不直接测试局部变量?
单元测试的核心是测试功能行为,而不是内部实现细节。局部变量属于实现细节,如果以后你修改了变量名、或者用其他方式实现相同的逻辑(比如直接用items.some(...)判断而不用变量),直接测试局部变量的测试用例就会失效,但实际功能是正常的。而测试行为或抽出来的公共逻辑,会让你的测试更稳定、更贴合实际需求。
内容的提问来源于stack exchange,提问作者Shailesh Ladumor
相关产品推荐
相关产品推荐

