我有以下装饰器,它包裹$timeout
内的原始$rootScope
。在控制器内部使用时,在范围被破坏时取消$timeout
承诺将有所帮助。
angular.module('MyApp').config(['$provide', function ($provide) {
$provide.decorator('$rootScope', ['$delegate', function ($delegate) {
Object.defineProperty($delegate.constructor.prototype, 'timeout', {
value: function (fn, number, invokeApply) {
var $timeout = angular.injector(['ng']).get('$timeout'),
promise;
promise = $timeout(fn, number, invokeApply);
this.$on('$destroy', function () {
$timeout.cancel(promise);
});
},
enumerable: false
});
return $delegate;
}]);
}]);
但我如何正确地对此进行单元测试?我有点看到我应该在这里进行2次测试... 1)检查调用$timeout
时是否调用了原$rootScope.timeout()
; 2)检查当范围被销毁时是否取消了承诺。< / p>
这是我目前的测试套件:
describe('MyApp', function () {
var $rootScope;
beforeEach(function () {
module('MyApp');
inject(['$rootScope', function (_$rootScope_) {
$rootScope = _$rootScope_;
}]);
});
describe('$timeout', function () {
it('<something>', function () {
$rootScope.timeout(function () {}, 2500);
// Test if the real $timeout was called with above parameters
$rootScope.$destroy();
// Test if the $timeout promise was destroyed
});
});
});
唯一能做的就是给我100%的报道。但那不是我想要的......我该如何正确测试呢?
答案 0 :(得分:0)
由于没有人能够帮助我,我真的想完成这项工作,我最终找到了自己的解决方案。我不确定这是最好的解决方案,但我认为它可以解决问题。
以下是我如何解决它:
describe('MyApp', function () {
var $rootScope,
$timeout,
deferred;
beforeEach(function () {
module('MyApp');
inject(['$rootScope', '$q', function (_$rootScope_, _$q_) {
$rootScope = _$rootScope_;
deferred = _$q_.defer();
}]);
$timeout = jasmine.createSpy('$timeout', {
cancel: jasmine.createSpy('$timeout.cancel')
}).and.returnValue(deferred.promise);
spyOn(angular, 'injector').and.returnValue({
get: function () {
return $timeout;
}
});
});
describe('$timeout', function () {
it('should set the timeout with the specified arguments', function () {
$rootScope.timeout(angular.noop, 250, false);
expect($timeout).toHaveBeenCalledWith(angular.noop, 250, false);
});
it('should cancel the timeout on scope destroy event', function () {
$rootScope.timeout(angular.noop, 250, false);
$rootScope.$destroy();
expect($timeout.cancel).toHaveBeenCalledWith(deferred.promise);
});
});
});