requestNotificationChannel
という角度のサービスがあります。
app.factory("requestNotificationChannel", function($rootScope) {
var _DELETE_MESSAGE_ = "_DELETE_MESSAGE_";
function deleteMessage(id, index) {
$rootScope.$broadcast(_DELETE_MESSAGE_, { id: id, index: index });
};
return {
deleteMessage: deleteMessage
};
});
私はjasmineを使ってこのサービスを単体テストしようとしています:
"use strict";
describe("Request Notification Channel", function() {
var requestNotificationChannel, rootScope, scope;
beforeEach(function(_requestNotificationChannel_) {
module("messageAppModule");
inject(function($injector, _requestNotificationChannel_) {
rootScope = $injector.get("$rootScope");
scope = rootScope.$new();
requestNotificationChannel = _requestNotificationChannel_;
})
spyOn(rootScope, '$broadcast');
});
it("should broadcast delete message notification", function(done) {
requestNotificationChannel.deleteMessage(1, 4);
expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4 });
done();
});
});
私はJasmineでの非同期サポートについて読みましたが、私はjavascriptを使った単体テストに慣れていないので、それを機能させることができませんでした。
エラーが発生しました。
Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL
そして私のテストは実行に時間がかかり過ぎています(約5秒)。
誰かが私のコードの実用的な例を説明付きで提供するのを手伝ってくれる?
it
関数(下記のコードのdone
)に引数を指定すると、Jasimneは非同期呼び出しを試みます。
//this block signature will trigger async behavior.
it("should work", function(done){
//...
});
//this block signature will run synchronously
it("should work", function(){
//...
});
done
引数の名前に違いはありません。その存在がすべて重要です。私はあまりにも多くのコピー/パスタからこの問題に遭遇しました。
Jasmin Asynchronous Support docsは、引数(上記のdone
)は非同期関数が完了したときにJasmineに知らせるために呼び出すことができるコールバックです。あなたがそれを決して呼び出さなければ、Jasmineはあなたのテストが完了したことを決して知らず、そして結局タイムアウトになります。
回避策として、非同期Jasmineコールバックを評価するために制限タイムアウトを増やすことができます。
describe('Helper', function () {
var originalTimeout;
beforeEach(function() {
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
});
afterEach(function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
it('Template advance', function(doneFn) {
$.ajax({
url: 'public/your-end-point.mock.json',
dataType: 'json',
success: function (data, response) {
// Here your expected using data
expect(1).toBe(1)
doneFn();
},
error: function (data, response) {
// Here your expected using data
expect(1).toBe(1)
doneFn();
}
});
});
});
出典: http://jasmine.github.io/2.0/introduction.html#section-42
このエラーは、サービス/ファクトリなどを初期化するときにinjectを省略することによっても引き起こされる可能性があります。例えば、こうすることでスローされます。
var service;
beforeEach(function(_TestService_) {
service = _TestService_;
});
これを修正するには、サービスを正しく取得するために単に関数をinjectでラップします。
var service;
beforeEach(inject(function(_TestService_) {
service = _TestService_;
}));
import { fakeAsync, ComponentFixture, TestBed } from '@angular/core/testing';
fakeAsyncを使用してください
beforeEach(fakeAsync (() => {
//your code
}));
describe('Intilalize', () => {
it('should have a defined component', fakeAsync(() => {
createComponent();
expect(_AddComponent.ngOnInit).toBeDefined();
}));
});
このエラーは、いつもうまくいっていたテストで、私にとっては真っ青から始まりました。私のMacBookが遅く走っているのに気づくまで、私は何の示唆も見つけることができなかった。 CPUが別のプロセスによって固定されていることに気付きました。 Jasmineの非同期エラーがなくなり、私のテストでも大丈夫です。
なぜ私に聞かないでください、私は知りません。しかし、私の状況では、それは誤ったシステムリソースの不足であるように思われました。
これは答えというよりは観察的なことですが、それは私のようにいらいらした他の人たちを助けるかもしれません。
私は自分のスイートの2つのテストからこのエラーを受け続けました。私は自分がしていたリファクタリングでテストを単純に壊したと思ったので、変更を取り消してもうまくいかなかった後は、エラーを取り除こうと思って以前のコードに2回戻りました。そうしても何も変わらなかった。私は昨日終日、そして問題を解決することなく今朝の一部を追いかけました。
私はイライラして今朝コードをラップトップにチェックアウトしました。テストスイート全体(約180のテスト)を実行しました。エラーはありません。そのため、エラーはコードやテストにはありませんでした。問題の原因となっている可能性があるメモリ内のものをすべてクリアするために、私の開発用ボックスに戻って再起動しました。変更なし、同じ2つのテストで同じエラー。そこで私は自分のマシンからそのディレクトリを削除し、そしてそれをチェックアウトした。ほら!エラーなし.
何が原因なのか、どのように修正するのかはわかりませんが、作業ディレクトリを削除してチェックアウトすると、修正されたものはすべて修正されました。
これが誰かに役立つことを願っています。
デフォルトのタイムアウト間隔をグローバルに設定するには、 karma-jasmine プラグインを使用できます。
この設定をkarma.conf.jsに追加します。
module.exports = function(config) {
config.set({
client: {
jasmine: {
timeoutInterval: 10000
}
}
})
}
私の場合、このエラーは "fixture.detectChanges()"の不適切な使用が原因で発生しました。このメソッドは変更が検出された場合にのみコールバックに応答するイベントリスナー(async)のようです。変更が検出されなかった場合、コールバックは呼び出されず、タイムアウトエラーが発生します。お役に立てれば :)
beforeAll
関数に何か期待しているときにもこのエラーが発生します。
describe('...', function () {
beforeAll(function () {
...
expect(element(by.css('[id="title"]')).isDisplayed()).toBe(true);
});
it('should successfully ...', function () {
}
}
scope
参照と関数の引数を削除した後に機能します。
"use strict";
describe("Request Notification Channel", function() {
var requestNotificationChannel, rootScope;
beforeEach(function() {
module("messageAppModule");
inject(function($injector, _requestNotificationChannel_) {
rootScope = $injector.get("$rootScope");
requestNotificationChannel = _requestNotificationChannel_;
})
spyOn(rootScope, "$broadcast");
});
it("should broadcast delete message notification with provided params", function() {
requestNotificationChannel.deleteMessage(1, 4);
expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4} );
});
});
done
関数に引数(it
)がある場合は、それを削除しようとします。関数自体の中で呼び出します。
it("should broadcast delete message notification", function(/*done -> YOU SHOULD REMOVE IT */) {
requestNotificationChannel.deleteMessage(1, 4);
expect(rootScope.$broadcast).toHaveBeenCalledWith("_DELETE_MESSAGE_", { id: 1, index: 4 });
// done(); -> YOU SHOULD REMOVE IT
});
@mastablastaで述べたように、 'done'引数を呼び出すか、あるいはそれに名前を付けたcompletedの場合は、コールバックcompleted()を呼び出しますテストが完了したら.
// this block signature will trigger async behavior.
it("should work", function(done){
// do stuff and then call done...
done();
});
// this block signature will run synchronously
it("should work", function(){
//...
});
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
これをブロックにしておくことで私の問題は解決しました。
it('', () => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
});
私がやったことは次のコードを追加/更新したことです:
framework: 'jasmine',
jasmineNodeOpts:
{
// Jasmine default timeout
defaultTimeoutInterval: 60000,
expectationResultHandler(passed, assertion)
{
// do something
},
}