我有一个简单的工厂
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); })); });
如何触发间隔或解决承诺?让测试成真?
解决方法
见
plunker
你需要使用angularjs-mocks中的‘$interval.flush’,然后测试结果.我已经冒昧地将计数分配给骰子对象,因为它在您的代码示例中未定义.
使用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',function($interval){ var self= { count: 0,rollDice: function(){ return $interval(function() { self.count++; },0); } }; return self; }]);
编辑:
我更喜欢测试函数调用的结果,但也许你有一个用例来测试一个promise函数被调用,所以这可能是你正在寻找的.从$interval上的角度文档中可以看出它返回
A promise which will be notified on each iteration.
关键字被通知.从promise API开始,当时的论点是
then(successCallback,errorCallback,notifyCallback)
即,对于$interval的每次迭代,调用第三个回调函数notifyCallback.所以测试看起来像这样:
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.