See plunker
You need to use '$interval.flush' from angularjs-mocks and then test for the result. I've taken the liberty to assign count
to the dice object because it's undefined in your code sample.
Is there any reason why $interval
is called with invokeApply = false
? because then you have to manually call $apply
.
The test case would be:
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);
}));
});
with factory:
app.factory('Dice', ['$interval', function($interval){
var self= {
count: 0,
rollDice: function(){
return $interval(function() {
self.count++;
}, 100, 18, false, 0);
}
};
return self;
}]);
EDIT:
I prefer testing the result of a function call but perhaps you have a use case for testing that a promise function is called so this might be what you're looking for. From the angular docs on $interval
it says it returns
A promise which will be notified on each iteration.
Keyword being notified. And from the promise API the arguments for then
are
then(successCallback, errorCallback, notifyCallback)
i.e. the third call back function notifyCallback
is called for each iteration of $interval
. So the test would look something like this:
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);
});
If you want to test for a resolved promise, then it would look something like this:
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');
});
I've updated the plunker with these test cases.
$interval.flush
but the$rootScope.$apply
is something new.... – Regent