以下は、テストしようとしているコードの単純化バージョンです。定期的に空になる単純なキューです。キュー内の各番号について、それを(この例では架空の)APIアドレスに送信するためのHTTP POSTが行われます。 POSTが成功すると、その番号はキューからシフトされ、次の番号が考慮されます。プロミスリターン関数を呼び出す再帰メソッドのユニットテスト
class Queue {
queue: Array<number>;
processingQueue: boolean;
constructor(public $http: angular.IHttpService) {
this.queue = new Array<number>();
this.processingQueue = false;
}
startQueueProcessor() {
this.processingQueue = false;
setInterval(() => {
if (!this.processingQueue)
this.processQueue();
}, 1000);
}
postNumber(number: number): angular.IHttpPromise<{}> {
return this.$http.post('http://mydummyurl.com/givemeanumber', number);
}
processQueue(): void {
this.processingQueue = true; // we are currently processing a queue, so make sure setInterval does not trigger another processing run
if (this.queue.length !== 0) { // are there any numbers to deal with?
const item = this.queue[0]; // get the first number in the queue
this.postNumber(item) // POST it (returns a promise)
.then(
() => { // if successful...
this.queue.shift(); // we've dealt with this item, so remove it from the queue
this.processQueue(); // check the queue again (recurses until all items have been dealt with)
},
() => { // if unsuccessful...
this.processingQueue = false; // something went wrong, so stop
}
);
} else {
this.processingQueue = false; // queue is empty, stop processing
}
}
enqueue(number: number): void { // add a number to the queue
this.queue.push(number);
}
}
私が作成したいテストはキューに追加された3つのアイテムを持った後、processQueue()
への単一の呼び出しがそれを空になる、ということをチェックします。 (ジャスミンにアップ嘲笑)このような
何か:
describe('queueing',() => {
var queueService;
beforeEach(inject((_$httpBackend_, $injector) => {
httpBackend = _$httpBackend_;
httpBackend.whenPOST().respond(200);
queueService = $injector.get('queue');
}));
it('should clear queue completely when processQueue() is called once',() => {
queueService.enqueue(1);
queueService.enqueue(2);
queueService.enqueue(3);
expect(queueService.queue.length).toBe(3);
queueService.processQueue();
// somehow wait for processQueue() to complete
expect(queueService.queue.length).toBe(0);
});
});
私の問題は、第二expect()
は常にメッセージExpected 3 to be 0
で失敗していることです。私はこれが、postNumber()
が待たずに返される約束によるものだと仮定しているので、第2のexpect()
が呼び出されるまでにキューは空ではありません。
processQueue()
が完了するのを待ってから、キューが空になったことをアサートします。
@Amidのご提案ありがとうございます。 'エラー:タイムアウト - 非同期コールバックがjasmine.DEFAULT_TIMEOUT_INTERVALで指定されたタイムアウト時間内に呼び出されていませんでした。 ' 最初のアサーションは正しく終了しましたが、' await'セクション何かを返すようではないとそれはタイムアウトします。 – Outrigger
私はそれには2つの理由があります。 http.postがホストに到達せず、操作がタイムアウトしました。または、(そしてこれはおそらく)angular.IHttpPromiseはtypescriptによって使用される一般的なA + promiseと互換性がありません。変換の例については、次の2つのリンクを参照してください。https://www.codeproject.com/articles/1019920/building-angularjs-application-with-typescript-and http://stackoverflow.com/questions/24611078/how-変換 - 角度 - 約束 - 遅延オブジェクト – Amid