Trudny / egzaminacyjny · lekcja 5
Testy jednostkowe w aplikacji webowej — xUnit i Jasmine/Karma
Aplikacja webowa (dział Aplikacje webowe) ma DWIE osobne warstwy kodu — backend ASP.NET Core i frontend Angular — i każda z nich wymaga WŁASNEGO podejścia do testowania, bo działają w zupełnie innych środowiskach uruchomieniowych (.NET po stronie serwera, Java...
Zacznij tutaj
Po co się tego uczymy?
Wprowadzenie
Teoria
Backend ASP.NET Core — xUnit zamiast MSTest. W projektach ASP.NET Core najpopularniejszym frameworkiem testowym jest xUnit (nie MSTest) — koncepcyjnie bardzo podobny (też AAA, też asercje), ale z inną składnią atrybutów: [Fact] zamiast [TestMethod] (pojedynczy test bez parametrów) i [Theory] + [InlineData(...)] zamiast [DataTestMethod] + [DataRow(...)] (test z wieloma zestawami danych). Asercje wyglądają inaczej składniowo: Assert.Equal(oczekiwany, wynik) (kolejność argumentów jak w MSTest), Assert.True(warunek), Assert.Throws<WyjątekTyp>(() => metoda()).
Testowanie kontrolerów Web API — testy jednostkowe kontra integracyjne. Kontroler API (poznany w lekcji o Web API/CORS, dział Aplikacje webowe) zwykle KORZYSTA z DbContext (Entity Framework Core) — testowanie go z PRAWDZIWĄ bazą danych to już test INTEGRACYJNY (wolniejszy, sprawdza współpracę z bazą). Żeby przetestować SAMĄ logikę kontrolera jednostkowo (szybko, bez bazy), używa się dostawcy EF Core InMemory — tymczasowej "bazy danych" trzymanej w pamięci RAM, tworzonej od zera dla każdego testu.
Frontend Angular — Jasmine i Karma. Projekt Angular utworzony przez Angular CLI ma testy skonfigurowane "od razu po wyjęciu z pudełka": Jasmine to framework do PISANIA testów (składnia describe(...) grupująca testy, it(...) pojedynczy test, expect(wynik).toBe(oczekiwany) asercja), a Karma to narzędzie URUCHAMIAJĄCE te testy w prawdziwej przeglądarce (uruchamiane komendą ng test).
TestBed — testowanie komponentów i serwisów Angular. TestBed to mechanizm Angulara tworzący "mini-środowisko" komponentu na potrzeby testu (bez uruchamiania całej aplikacji) — pozwala utworzyć instancję komponentu lub serwisu, wstrzyknąć jego zależności (Dependency Injection, poznane w lekcji o serwisach Angular) i sprawdzić zachowanie. Dla PROSTYCH serwisów (bez zależności od Angulara, np. czysta logika obliczeniowa) można też testować JAK ZWYKŁĄ klasę TypeScript, bez TestBed w ogóle.
Mockowanie zależności HTTP w Angularze — serwis korzystający z HttpClient (do komunikacji z Web API) NIE powinien w teście jednostkowym wysyłać PRAWDZIWEGO żądania sieciowego. Angular dostarcza HttpClientTestingModule — "atrapę" (mock) modułu HTTP, która pozwala symulować odpowiedzi serwera i sprawdzać, jakie żądania serwis faktycznie wysłał, bez łączenia się z prawdziwym backendem.
Zobacz zależności
Schemat
APLIKACJA WEBOWA — DWIE warstwy, DWA różne narzędzia testowe
BACKEND (ASP.NET Core) FRONTEND (Angular)
┌─────────────────────┐ ┌─────────────────────┐
│ WpisyController.cs │ │ feed.component.ts │
│ (Web API) │ │ (komponent) │
└──────────┬───────────┘ └──────────┬───────────┘
│ testowany przez │ testowany przez
▼ ▼
xUnit + EF Core InMemory Jasmine + Karma + TestBed
[Fact] / [Theory] describe() / it() / expect()
Assert.Equal(...) TestBed.createComponent(...)
dotnet test ng test
Połącz z praktyką
Przykład z życia
Duży sklep internetowy ma osobny zespół backendowy (API, baza danych, reguły cenowe) i osobny zespół frontendowy (interfejs, koszyk, formularze) — każdy zespół testuje swoją część NIEZALEŻNIE, własnymi narzędziami dopasowanymi do swojego języka i środowiska, ale oba kierują się TĄ SAMĄ filozofią: testuj logikę w izolacji, sprawdzaj przypadki brzegowe, nie testuj wyglądu. Dzięki temu obie warstwy można rozwijać równolegle, mając pewność, że zmiana w jednej nie zepsuje cichaczem drugiej.