AngularJS Karma-Jasmine单元测试:如何验证$q.when().finally回调内容
嘿,这个问题我刚好踩过坑,给你捋清楚怎么处理哈!
验证$q.when().finally回调的方法
首先明确:不需要额外Mock$q,AngularJS的测试套件已经帮我们注入了原生的$q服务,但有个核心关键点——$q的promise是依赖Angular的digest循环来触发状态变更的,所以你得手动触发digest才能让finally回调执行。
具体步骤&代码示例
假设你的业务代码是这样的:
// 业务代码示例 function runFinallyCallback() { $q.when().finally(function () { console.log("I am testing"); // 也可能是把值赋值给某个变量,比如 vm.notice = "I am testing" }); }
1. 准备测试环境,注入核心依赖
在Jasmine测试用例里,先注入$q和$rootScope(后者用来触发digest循环)。
2. 编写完整测试用例
如果是用console.log输出内容,我们可以通过Spy监听console.log来捕获输出;如果是赋值给变量,直接断言变量值即可。这里以console.log为例:
describe('Testing $q.when().finally callback', function() { var $q, $rootScope; // 替换成你的Angular模块名 beforeEach(module('yourAppModule')); beforeEach(inject(function(_$q_, _$rootScope_) { $q = _$q_; $rootScope = _$rootScope_; // 监听console.log,方便后续验证 spyOn(console, 'log'); })); it('should trigger finally callback and output "I am testing"', function() { // 调用包含finally回调的业务函数 runFinallyCallback(); // 重中之重!触发digest循环,让$q的promise状态变更,执行finally回调 $rootScope.$digest(); // 验证输出是否符合预期 expect(console.log).toHaveBeenCalledWith("I am testing"); }); });
关键注意事项
- 必须触发$digest/$apply:$q的promise是Angular内部实现的,只有在digest循环运行时才会检查promise状态并执行回调。忘了这一步的话,finally回调永远不会执行,测试必败。
- 如果业务代码里的promise来自其他服务(比如$http),那才需要Mock对应服务,但这里是
$q.when()——它本身是立即resolve的空promise,所以完全不需要额外Mock。 - 如果不是用
console.log,而是把值绑定到scope或服务变量里,直接断言变量值即可。比如业务代码是vm.notice = "I am testing",测试里就写expect(vm.notice).toBe("I am testing"),前提是先触发$rootScope.$digest()。
内容的提问来源于stack exchange,提问作者Cloud_cal
相关产品推荐
相关产品推荐

