在 Jasmine/Karma 中测试 $interval
Testing $interval in Jasmine/ Karma
我有一个简单的工厂
angular.module('myApp.dice',[]).factory('Dice', ['$interval', function($interval){
return {
rollDice: function(){
return $interval(function(c){
count++;
}, 100, 18, false, 0);
}
};
}]);
在我的测试用例中我有
describe('rolling dice', function(){
var promise, promiseCalled = false, notify = false;
beforeEach(inject(function(){
promise = Dice.rollDice();
promise.then(function(){
promiseCalled = true;
});
}));
it('should invoke a promise', inject(function(){
expect(promise).toBeDefined();
}));
it('should set promiseCalled', inject(function($rootScope, $interval){
expect(promiseCalled).toEqual(true);
}));
});
如何触发间隔或解决承诺?让测试是真的?
您需要使用 angularjs-mocks 中的 '$interval.flush' 然后测试结果。我冒昧地将 count
分配给 dice 对象,因为它在您的代码示例中未定义。
用invokeApply = false
调用$interval
有什么原因吗?因为那时你必须手动调用 $apply
.
测试用例为:
describe('rolling dice', function(){
var $interval, $rootScope, dice;
beforeEach(module('plunker'));
beforeEach(inject(function(_$interval_, _$rootScope_, _Dice_){
$interval = _$interval_;
$rootScope = _$rootScope_;
dice = _Dice_;
}));
it('should increment count', inject(function(){
dice.rollDice();
// Move forward by 100 milliseconds
$interval.flush(100);
// Need to call apply because $interval was called with invokeApply = false
$rootScope.$apply();
expect(dice.count).toBe(1);
}));
});
与工厂:
app.factory('Dice', ['$interval', function($interval){
var self= {
count: 0,
rollDice: function(){
return $interval(function() {
self.count++;
}, 100, 18, false, 0);
}
};
return self;
}]);
编辑:
我更喜欢测试函数调用的结果,但也许您有一个用例来测试调用了 promise 函数,所以这可能就是您要找的。从 $interval
上的 angular 文档中可以看出 returns
A promise which will be notified on each iteration.
关键字正在通知。 promise API then
的参数是
then(successCallback, errorCallback, notifyCallback)
即第三个回调函数 notifyCallback
在 $interval
的每次迭代中被调用。所以测试看起来像这样:
it('should set promiseCalled', function(){
var promiseCalled = false;
dice.rollDice().then(null, null, function() {
promiseCalled = true;
});
$interval.flush(100);
$rootScope.$apply();
expect(promiseCalled).toBe(true);
});
如果你想测试一个已解决的承诺,那么它看起来像这样:
it('should resolve promise', function(){
var promiseCalled = false;
var resolvedData = null;
$q.when('Some Data').then(function(data) {
promiseCalled = true;
resolvedData = data;
});
$rootScope.$apply();
expect(promiseCalled).toBe(true);
expect(resolvedData).toBe('Some Data');
});
我已经用这些测试用例更新了 plunker。
我有一个简单的工厂
angular.module('myApp.dice',[]).factory('Dice', ['$interval', function($interval){
return {
rollDice: function(){
return $interval(function(c){
count++;
}, 100, 18, false, 0);
}
};
}]);
在我的测试用例中我有
describe('rolling dice', function(){
var promise, promiseCalled = false, notify = false;
beforeEach(inject(function(){
promise = Dice.rollDice();
promise.then(function(){
promiseCalled = true;
});
}));
it('should invoke a promise', inject(function(){
expect(promise).toBeDefined();
}));
it('should set promiseCalled', inject(function($rootScope, $interval){
expect(promiseCalled).toEqual(true);
}));
});
如何触发间隔或解决承诺?让测试是真的?
您需要使用 angularjs-mocks 中的 '$interval.flush' 然后测试结果。我冒昧地将 count
分配给 dice 对象,因为它在您的代码示例中未定义。
用invokeApply = false
调用$interval
有什么原因吗?因为那时你必须手动调用 $apply
.
测试用例为:
describe('rolling dice', function(){
var $interval, $rootScope, dice;
beforeEach(module('plunker'));
beforeEach(inject(function(_$interval_, _$rootScope_, _Dice_){
$interval = _$interval_;
$rootScope = _$rootScope_;
dice = _Dice_;
}));
it('should increment count', inject(function(){
dice.rollDice();
// Move forward by 100 milliseconds
$interval.flush(100);
// Need to call apply because $interval was called with invokeApply = false
$rootScope.$apply();
expect(dice.count).toBe(1);
}));
});
与工厂:
app.factory('Dice', ['$interval', function($interval){
var self= {
count: 0,
rollDice: function(){
return $interval(function() {
self.count++;
}, 100, 18, false, 0);
}
};
return self;
}]);
编辑:
我更喜欢测试函数调用的结果,但也许您有一个用例来测试调用了 promise 函数,所以这可能就是您要找的。从 $interval
上的 angular 文档中可以看出 returns
A promise which will be notified on each iteration.
关键字正在通知。 promise API then
的参数是
then(successCallback, errorCallback, notifyCallback)
即第三个回调函数 notifyCallback
在 $interval
的每次迭代中被调用。所以测试看起来像这样:
it('should set promiseCalled', function(){
var promiseCalled = false;
dice.rollDice().then(null, null, function() {
promiseCalled = true;
});
$interval.flush(100);
$rootScope.$apply();
expect(promiseCalled).toBe(true);
});
如果你想测试一个已解决的承诺,那么它看起来像这样:
it('should resolve promise', function(){
var promiseCalled = false;
var resolvedData = null;
$q.when('Some Data').then(function(data) {
promiseCalled = true;
resolvedData = data;
});
$rootScope.$apply();
expect(promiseCalled).toBe(true);
expect(resolvedData).toBe('Some Data');
});
我已经用这些测试用例更新了 plunker。