async
nie pozwoli na rozpoczęcie następnego testu, dopóki nie async
zakończy wszystkich jego zadań. To, co async
robi, to zawijanie wywołania zwrotnego w strefie, w której setTimeout
śledzone są wszystkie zadania asynchroniczne (np. ). Po ukończeniu wszystkich zadań asynchronicznych następuje async
zakończenie.
Jeśli kiedykolwiek pracowałeś z Jasmine poza Angularem, być może widziałeś done
, jak przechodzisz do oddzwaniania
it('..', function(done) {
someAsyncAction().then(() => {
expect(something).toBe(something);
done();
});
});
Tutaj jest to rodzima Jasmine, gdzie mówimy Jasmine, że ten test powinien opóźnić zakończenie do czasu, gdy zadzwonimy done()
. Jeśli nie zadzwoniliśmy, done()
a zamiast tego zrobiliśmy to:
it('..', function() {
someAsyncAction().then(() => {
expect(something).toBe(something);
});
});
Test zakończyłby się jeszcze przed oczekiwaniem, ponieważ obietnica rozwiązuje się po zakończeniu testu podczas wykonywania zadań synchronicznych.
Z Angular (w środowisku Jasmine), Angular będzie w rzeczywistości wywoływał done
za kulisami, gdy używamy async
. Będzie śledził wszystkie asynchroniczne zadania w Strefie, a gdy wszystkie zostaną zakończone, done
zostaną wywołane za kulisami.
W twoim konkretnym przypadku z TestBed
konfiguracją, użyjesz tego ogólnie, kiedy chcesz compileComponents
. Rzadko spotykam się z sytuacją, w której musiałbym inaczej to nazwać
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyModule],
schemas: [NO_ERRORS_SCHEMA],
})
.compileComponent().then(() => {
fixture = TestBed.createComponent(TestComponent);
});
}));
Podczas testowania komponentu, który używa templateUrl
(jeśli nie używasz webpacka), Angular musi wysłać żądanie XHR, aby pobrać szablon, więc kompilacja komponentu byłaby asynchroniczna. Dlatego przed kontynuowaniem testów powinniśmy poczekać, aż problem zniknie.
async
nie jest to konieczne. Kiedy używasztemplateUrl
, tak jest. Jednak uwzględnienieasync
nie spowoduje „zerwania” komponentu szablonu wbudowanego. Czy uważasz, że można bezpiecznie powiedzieć, że można po prostu domyślnie używaćasync
do każdego testu?compileComponents
. Nie ma to nic wspólnego z używaniemasync
w każdym teście, jeśli o to pytasz. Jeśli chodzi o bezpieczeństwo (kiedy powinieneś zadzwonićcompileComponents
), zobacz Kiedy mam zadzwonić do compileComponentsngOnInit
wywoływany jest komponent. Czasami ma to znaczenie podczas testówGdy wykonujesz wywołanie asynchroniczne w teście, rzeczywista funkcja testowa zostanie zakończona przed zakończeniem wywołania asynchronicznego. Gdy trzeba zweryfikować stan zakończenia wywołania (co zwykle ma miejsce), platforma testowa zgłosi test jako zakończony, podczas gdy nadal trwają prace asynchroniczne.
Używając,
async(...)
możesz powiedzieć platformie testowej, aby poczekała, aż obietnica zwrotu lub obserwowalna zostanie zakończona, zanim potraktujesz test jako zakończony.Kod przekazany do
then(...)
zostanie wykonany po zakończeniu samej funkcji testowej. Dzięki temuasync()
środowisko testowe będzie świadome, że musi czekać na wypełnienie obietnic i obserwacji, zanim potraktuje test jako zakończony.Zobacz też
źródło