2016-10-19 14 views
25

Kiedy używasz funkcji asynchronicznej w TestBed podczas testowania w Angular 2?Testowanie kątowe 2 - Wywołanie funkcji asynchronicznej - kiedy używać

Kiedy używasz tego?

beforeEach(() => { 
     TestBed.configureTestingModule({ 
      declarations: [MyModule], 
      schemas: [NO_ERRORS_SCHEMA], 
     }); 
    }); 

i kiedy używasz tego?

beforeEach(async(() => { 
     TestBed.configureTestingModule({ 
      declarations: [MyModule], 
      schemas: [NO_ERRORS_SCHEMA], 
     }); 
    })); 

Czy ktoś może mnie o tym poinformować?

Odpowiedz

32

async pozwoli następny test nie rozpocznie, dopóki async wykończeniach wszystkich jego zadań. To, co robi async, zawija wywołanie zwrotne w strefie, w której śledzone są wszystkie asynchroniczne zadania (na przykład setTimeout). Po zakończeniu wszystkich zadań asynchronicznych zakończy się proces async.

Jeśli kiedykolwiek pracował z Jasmine zewnątrz out kątowe, może widzieliście done są przekazywane do zwrotnego

it('..', function(done) { 
    someAsyncAction().then(() => { 
    expect(something).toBe(something); 
    done(); 
    }); 
}); 

Tutaj jest to rodzimy jaśmin, gdzie mówimy Jasmine że test ten powinien opóźnić ukończenie aż dzwonimy pod numer done(). Jeśli nie zrobiliśmy tego

it('..', function() { 
    someAsyncAction().then(() => { 
    expect(something).toBe(something); 
    }); 
}); 

Test zakończy się jeszcze przed oczekiwaniem, bo obietnica postanawia po zakończeniu testu synchroniczne wykonanie zadania.

W przypadku kątowego (w środowisku jaśminowym) Angular będzie wywoływał za kulisami done, gdy używamy async. Będzie śledzić wszystkie asynchroniczne zadania w Strefie, a kiedy wszystko się skończy, done zostanie wywołany za kulisami.

W konkretnym przypadku z konfiguracją TestBed, możesz użyć tego ogólnie, gdy chcesz compileComponents.Rzadko zdarza mi się uruchomić w sytuacji, w której musiałbym nazwać inaczej

beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
    declarations: [MyModule], 
    schemas: [NO_ERRORS_SCHEMA], 
    }) 
    .compileComponent().then(() => { 
     fixture = TestBed.createComponent(TestComponent); 
    }); 
})); 

Testując komponent, który używa templateUrl (jeśli nie używasz WebPACK), a następnie kątowa musi złożyć wniosek XHR dostać szablon , więc kompilacja komponentu byłaby asynchroniczna. Powinniśmy więc poczekać, aż to rozwiąże, aby kontynuować testowanie.

+0

Świetna odpowiedź @peeskillet. Aby upewnić się, że rozumiem: Gdy masz wbudowany szablon, 'asynchroniczne' nie jest konieczne. Kiedy używasz 'templateUrl', to jest. Jednak włączenie 'async' nie" złamie "składnika wbudowanego szablonu. Czy sądzisz, że można bezpiecznie powiedzieć, że po każdym teście można użyć 'async'? – vincecampanale

+1

@vincecampanale SzablonUrl ma znaczenie tylko podczas konfiguracji w beforeEach. W takim przypadku musisz wywołać 'compileComponents'. Nie ma to nic wspólnego z użyciem 'async' na każdym teście, jeśli o to pytasz. O ile jest to bezpieczne (kiedy powinieneś zadzwonić do 'compileComponents'), zobacz [Kiedy mam zadzwonić do compileComponents] (https://stackoverflow.com/q/43608398/2587435) –

+0

Rozumiem. Inne pytanie: Angularny interfejs CLI generuje testy, które nazywają 'fixture.detectChanges()' w 'beforeEach()'. Czy najlepiej jest zawsze wywoływać tę funkcję przed uruchomieniem każdego testu? Jeśli uważasz, że to nie ma związku, chętnie odpowiem osobno na to pytanie. – vincecampanale

8

Podczas wykonywania połączenia asynchronicznego w teście faktyczna funkcja testu zostaje zakończona przed zakończeniem połączenia asynchronicznego. Gdy trzeba zweryfikować jakiś stan, gdy połączenie zostało zakończone (co zwykle ma miejsce), struktura testowa zgłosi test jako zakończony, gdy nadal będzie trwała praca asynchroniczna.

Przy użyciu async(...) podajesz ramowi testowemu, aby poczekał, aż obietnica zwrotu lub obserwowalna zostanie zakończona przed traktowaniem testu jako zakończonego.

it('should show quote after getQuote promise (async)', async(() => { 
    fixture.detectChanges(); 

    fixture.whenStable().then(() => { // wait for async getQuote 
    fixture.detectChanges();  // update view with quote 
    expect(el.textContent).toBe(testQuote); 
    }); 
})); 

Kod przekazany do then(...) zostanie wykonany po funkcję testową sam wypełniony. Dzięki async() uświadamiasz system testowy, że musi on czekać na dotrzymanie obietnic i obserwowalnych wyników, zanim traktujesz test jako ukończony.

Zobacz także

Powiązane problemy