私は定期的な間隔で繰り返し呼び出されたいangularサービスの1つに関数があります。$ timeoutを使用してこれを行いたいです。
_var interval = 1000; // Or something
var _tick = function () {
$timeout(function () {
doStuff();
_tick();
}, interval);
};
_tick();
_
現在、ジャスミンでこれを単体テストする方法に困惑しています-どうすればいいですか? $timeout.flush()
を使用すると、関数呼び出しは無期限に発生します。 Jasmineのモッククロックを使用する場合、_$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();
});
});
_
これら2つのバリエーションは機能しますが、私には役立ちません:
_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();
});
});
_
前もって感謝します!
Jasmineのクロックを使用してテストを非同期にしないでください。代わりに、$timeout.flush()
を使用して、テストのフローを同期的に維持します。セットアップするのは少し難しいかもしれませんが、一度取得すれば、テストはより速く、より制御されます。
このアプローチを使用してそれを行うテストの例を次に示します。 https://github.com/angular/angular.js/blob/master/test/ngAnimate/animateSpec.js#L618
@matskoの答えは私を正しい道に導いた。答えを見つけやすくするために、「完全な」解決策を投稿すると思いました。
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();
});
});