簡體   English   中英

使用jasmine進行Angular2異步單元測試

[英]Angular2 async unit testing with jasmine

我正在編寫一個angular2應用程序,並且無法理解如何使用jasmine編寫異步代碼的測試。 無論出於何種原因,我都沒有看到很多看似非常適用於我的情況的例子。

我目前正在嘗試測試對另一個服務具有異步依賴性的服務(而不是組件)。 我不是100%確定測試中的哪一點檢查異步調用的結果是有效的。 你能在服務的異步處理程序中調用expect()嗎?

service.foo()
    .then((data) => {
        //do I check the results in here?
        expect(data).toEqual({ a: 1, b: 2 });
        expect(mockDep.get).toHaveBeenCalled();
    });

這是完整的測試。

import { TestBed, inject } from '@angular/core/testing';
import { MyService } from './my.service.ts';
import { MyDependency } from './dependency.service.ts';

class MockDependency {
    doSomething(): Promise<any> {
        throw Error('not implemented');
    };
}

describe('some tests', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                MyService,
                {
                    provide: MyDependency, useClass: MockDependency
                }
            ]
        });
    });
});

it('should do something', inject([MyService, MyDependency], (service: MyService, mockDep: MyDependency) => {
    spyOn(mockDep, 'doSomething').and.callFake(function () {
        return Promise.resolve({ a: 1, b: 2 });
    });

    service.foo()
        .then((data) => {
            //do I check the results in here?
            expect(data).toEqual({ a: 1, b: 2 });
            expect(mockDep.get).toHaveBeenCalled();
        });
}));

處理異步測試有兩個方面,如果你想確保測試真正可靠,你必須關注它們。

首先,您必須確保如果異步檢索結果,則在嘗試測試結果之前等待結果可用。

因此,如果異步結果是一個承諾,例如,您可以將您的expect放在then處理程序中,就像您在問題中指出的那樣。

您必須關注的第二個問題是強制您的測試本身在給出積極(或消極)結果之前等待您的期望執行。 如果你不處理這個問題,你可能會遇到期望失敗的情況,但是因為你的測試沒有等到你的異步操作在完成之前完成,所以測試會報告誤報。

有幾種方法可以“讓你的測試等待”。

純粹的茉莉花方式是將一個done處理程序傳遞給你的it函數。 然后jasmine將等待,直到調用完成處理程序,然后才考慮完成測試。

例如。

it('tests an async action', (done) => {
   asyncAction().then(result => {
     expect(result).toEqual(true);
     done();
   });
});

但是,angular的測試框架為此添加了兩個其他選項。 如果您對異步編程感到滿意,那么第一個更容易掌握。

it('tests an async action', async(() => {
   asyncAction().then(result => {
     expect(result).toEqual(true);
   });
}));

在這種情況下,您基本上將測試處理程序包裝在異步函數中。 在允許測試完成之前,此函數將強制測試等待任何異步結果(例如promises,observables等)返回結果。

第二種方法是使用fakeAsync,它允許您完全隱藏測試的異步性質。

it('tests an async action', fakeAsync(() => {
   let myResult;
   asyncAction().then(result => {
     myResult = result;
   });

   tick();   <--- force all async actions to complete
   expect(myResult).toEqual(true);
}));

fakeAsync掛鈎到所有異步函數,並允許您將它們視為同步。 您可以使用tick()函數“強制您的測試等待”,以便在繼續之前完成異步任務。
(這不是那么做,但從概念上講,你可以這樣想)。

請參閱Angular文檔以了解更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM