unit testing使用$超时与茉莉花的模拟时钟的angular度服务

我在我的一个angular度服务里面有一个函数,我想定期重复地调用它。 我想这样做使用$超时。 它看起来像这样:

var interval = 1000; // Or something var _tick = function () { $timeout(function () { doStuff(); _tick(); }, interval); }; _tick(); 

我现在很难与Jasmine一起进行unit testing – 我该怎么做? 如果我使用$timeout.flush()则函数调用将无限期地发生。 如果我使用茉莉花的模拟时钟, $timeout似乎不受影响。 基本上,如果我能得到这个工作,我应该很好去:

 describe("ANGULAR Manually ticking the Jasmine Mock Clock", function() { var timerCallback, $timeout; beforeEach(inject(function($injector) { $timeout = $injector.get('$timeout'); timerCallback = jasmine.createSpy('timerCallback'); jasmine.Clock.useMock(); })); it("causes a timeout to be called synchronously", function() { $timeout(function() { timerCallback(); }, 100); expect(timerCallback).not.toHaveBeenCalled(); jasmine.Clock.tick(101); expect(timerCallback).toHaveBeenCalled(); }); }); 

这两个变化的工作,但不帮助我:

 describe("Manually ticking the Jasmine Mock Clock", function() { var timerCallback; beforeEach(function() { timerCallback = jasmine.createSpy('timerCallback'); jasmine.Clock.useMock(); }); it("causes a timeout to be called synchronously", function() { setTimeout(function() { timerCallback(); }, 100); expect(timerCallback).not.toHaveBeenCalled(); jasmine.Clock.tick(101); expect(timerCallback).toHaveBeenCalled(); }); }); describe("ANGULAR Manually flushing $timeout", function() { var timerCallback, $timeout; beforeEach(inject(function($injector) { $timeout = $injector.get('$timeout'); timerCallback = jasmine.createSpy('timerCallback'); })); it("causes a timeout to be called synchronously", function() { $timeout(function() { timerCallback(); }, 100); expect(timerCallback).not.toHaveBeenCalled(); $timeout.flush(); expect(timerCallback).toHaveBeenCalled(); }); }); 

提前致谢!

不要使用茉莉花的时钟进行testingasynchronous。 相反,使用$timeout.flush()来同步维护testing的stream程。 设置可能有点棘手,但一旦你得到它,那么你的testing将会更快,更受控制。

这是一个testing的例子,它使用这种方法: https : //github.com/angular/angular.js/blob/master/test/ngAnimate/animateSpec.js#L618

@ matsko的回答让我走上了正确的道路。 我想我会发布我的“完整”的解决scheme,使其更容易find答案。

要testing的东西

 angular.module("app").service("MyService", function() { return { methodThatHasTimeoutAndReturnsAPromise: function($q, $timeout) { var deferred = $q.defer(); $timeout(function() { deferred.resolve(5); }, 2000); return deferred.promise; } }; }); 

考试

 describe("MyService", function() { var target, $timeout; beforeEach(inject(function(_$timeout_, MyService) { $timeout = _$timeout_; target = MyService; })); beforeEach(function(done) { done(); }); it("equals 5", function(done) { target.methodThatHasTimeoutAndReturnsAPromise().then(function(value) { expect(value).toBe(5); done(); }); $timeout.flush(); }); });