使用 Jasmine 在 AngularJS 中测试去抖动函数永远不会调用该函数
Testing a debounced function in AngularJS with Jasmine never calls the function
我在使用下划线去抖的服务中有一个方法。
该方法内部是对不同服务上的方法的调用。我正在尝试测试是否调用了不同的服务。
在我尝试测试去抖动方法时,从未调用过不同服务的方法,茉莉花失败了:
"Expected spy aMethod to have been called."
我知道它被调用的事实(它在 chrome 中记录到控制台),它只是在期望已经失败之后被调用。
所以...(最好)不添加 Sinon 或其他依赖项并且
给予解决方案的奖励积分*不必将 _.debounce 变成 $timeout...
怎么办?
angular.module('derp', [])
.service('herp', function(){
return {
aMethod: function(){
console.log('called!');
return 'blown';
}
};
})
.service('Whoa', ['herp', function(herp){
function Whoa(){
var that = this;
this.mindStatus = 'meh';
this.getMind = _.debounce(function(){
that.mindStatus = herp.aMethod();
}, 300);
}
return Whoa;
}]);
测试:
describe('Whoa', function(){
var $injector, whoa, herp;
beforeEach(function(){
module('derp');
inject(function(_$injector_){
var Whoa;
$injector = _$injector_;
Whoa = $injector.get('Whoa');
herp = $injector.get('herp');
whoa = new Whoa();
});
});
beforeEach(function(){
spyOn(herp, 'aMethod').andCallThrough();
});
it('has a method getMind, that calls herp.aMethod', function(){
whoa.getMind();
expect(herp.aMethod).toHaveBeenCalled();
});
});
为什么AngularJS试炼之神抛弃了我?
* 我不知道如何在 Whosebug 上给出实际的奖励积分,但如果可能的话,我会的。
你只需要模拟 lodash 去抖动方法:
describe('Whoa', function(){
var $injector, whoa, herp;
beforeEach(function(){
module('derp');
spyOn(_, 'debounce').and.callFake(function(cb) { return function() { cb(); } });
inject(function(_$injector_){
var Whoa;
$injector = _$injector_;
Whoa = $injector.get('Whoa');
herp = $injector.get('herp');
whoa = new Whoa();
});
});
beforeEach(function(){
spyOn(herp, 'aMethod').andCallThrough();
});
it('has a method getMind, that calls herp.aMethod', function(){
whoa.getMind();
expect(herp.aMethod).toHaveBeenCalled();
});
});
Angular $timeout
在测试中有优势,因为它在测试中被模拟为同步的。使用 third-party 个异步工具时,将没有此优势。一般来说,异步规范看起来像这样:
var maxDelay = 500;
...
it('has a method getMind, that calls herp.aMethod', function (done){
whoa.getMind();
setTimeout(function () {
expect(herp.aMethod).toHaveBeenCalled();
done();
}, maxDelay);
});
由于 Underscore debounce
不提供 flush
功能(而最新版本的 Lodash debounce
does),异步测试是可用的最佳选择。
我的 debounced 函数接受了参数,所以我像这样嘲笑 _.debounce
spyOn(_, 'debounce').and.callFake(function(cb) {return cb});
(对@Wawy 的回答略作修改)
我在使用下划线去抖的服务中有一个方法。
该方法内部是对不同服务上的方法的调用。我正在尝试测试是否调用了不同的服务。
在我尝试测试去抖动方法时,从未调用过不同服务的方法,茉莉花失败了:
"Expected spy aMethod to have been called."
我知道它被调用的事实(它在 chrome 中记录到控制台),它只是在期望已经失败之后被调用。
所以...(最好)不添加 Sinon 或其他依赖项并且
给予解决方案的奖励积分*不必将 _.debounce 变成 $timeout...
怎么办?
angular.module('derp', [])
.service('herp', function(){
return {
aMethod: function(){
console.log('called!');
return 'blown';
}
};
})
.service('Whoa', ['herp', function(herp){
function Whoa(){
var that = this;
this.mindStatus = 'meh';
this.getMind = _.debounce(function(){
that.mindStatus = herp.aMethod();
}, 300);
}
return Whoa;
}]);
测试:
describe('Whoa', function(){
var $injector, whoa, herp;
beforeEach(function(){
module('derp');
inject(function(_$injector_){
var Whoa;
$injector = _$injector_;
Whoa = $injector.get('Whoa');
herp = $injector.get('herp');
whoa = new Whoa();
});
});
beforeEach(function(){
spyOn(herp, 'aMethod').andCallThrough();
});
it('has a method getMind, that calls herp.aMethod', function(){
whoa.getMind();
expect(herp.aMethod).toHaveBeenCalled();
});
});
为什么AngularJS试炼之神抛弃了我?
* 我不知道如何在 Whosebug 上给出实际的奖励积分,但如果可能的话,我会的。
你只需要模拟 lodash 去抖动方法:
describe('Whoa', function(){
var $injector, whoa, herp;
beforeEach(function(){
module('derp');
spyOn(_, 'debounce').and.callFake(function(cb) { return function() { cb(); } });
inject(function(_$injector_){
var Whoa;
$injector = _$injector_;
Whoa = $injector.get('Whoa');
herp = $injector.get('herp');
whoa = new Whoa();
});
});
beforeEach(function(){
spyOn(herp, 'aMethod').andCallThrough();
});
it('has a method getMind, that calls herp.aMethod', function(){
whoa.getMind();
expect(herp.aMethod).toHaveBeenCalled();
});
});
Angular $timeout
在测试中有优势,因为它在测试中被模拟为同步的。使用 third-party 个异步工具时,将没有此优势。一般来说,异步规范看起来像这样:
var maxDelay = 500;
...
it('has a method getMind, that calls herp.aMethod', function (done){
whoa.getMind();
setTimeout(function () {
expect(herp.aMethod).toHaveBeenCalled();
done();
}, maxDelay);
});
由于 Underscore debounce
不提供 flush
功能(而最新版本的 Lodash debounce
does),异步测试是可用的最佳选择。
我的 debounced 函数接受了参数,所以我像这样嘲笑 _.debounce
spyOn(_, 'debounce').and.callFake(function(cb) {return cb});
(对@Wawy 的回答略作修改)