w Praktyce
7 godz. 1 min · Angular · Full-stack i Programowanie
Mateusz KuleszaSenior Software Developer, Konsultant, TrenerPodstawą produktywnej pracy z angularem jest możliwość zagwarantowania że wszystko działa bez potrzeby wielokrotnego “przeklikiwania” poszczególnych ekranów. W pierwszej części kursu omawiam więc temat testów automatycznych.Już po obejrzeniu pierwszych lekcji zobaczysz dlaczego warto testować kod i jak dzięki narzędziom dostarczonym z angularem jest to proste. Zobaczysz jak testowanie automatyczne pozwoli zaoszczędzić Ci wiele godzin spędzonych na szukaniu błędów.
Za jakość aplikacji odpowiada nie tylko to czy działa ona poprawnie, ale w dużej mierze decyduje o tym dobry interfejs użytkownika oraz UX, czyli user experience. Dwie kolejne sekcje kursu poświęcone są właśnie dobremu UI oraz UX. Omawiam typowe problemy w oparciu o zasady i wskazówki specyfikacji Google Material Design - jednej z najbardziej szczegółowych specyfikacji UX. Wszystkie przykłady UI zarówno w wariantach desktopowych jak i mobilnych omówione są na przykładzie Angulara oraz obszernej biblioteki komponentów Angular Material. Zobaczysz nie tylko jak korzystając z gotowych komponentów błyskawicznie budować nowe funkcjonalności, ale przy okazji omówimy wiele praktycznych wskazówek oraz dobrych praktyk UX które warto wykorzystać w Twoich aplikacjach.
W ramach budowania interfejsów skupimy się na najmniejszych szczegółach takich jak prawidłowe zachowanie linków, przycisków oraz wskaźników przechodząc stopniowo do coraz większych elementów aplikacji takich jak nawigacja, układ strony, paski nawigacyjne czy okna dialogowe. Przy każdym etapie czeka Cię masa wskazówek, przykładów i rozwiązań typowych problemów user experience.
Jednak UX to nie tylko wygląd i zachowanie pojedynczych elementów. W ostatnich sekcjach kursu dowiesz się jak projektować bardziej złożone interakcje z użytkownikiem. Zobaczysz wieloetapowe formularze kreatora oraz dowiesz się jak zarządzać stanem aplikacji oraz różnymi źródłami danych. Pokaże Ci jak zbudować samodzielnie sortowane, filtrowane i stronicowane źródła danych oraz połączyć je z różnymi komponentami UI takimi jak listy czy datagrid.
Na koniec kursu zobaczysz jak możemy różne gotowe elementy UI połączyć w przepływ ekranów budując ścieżkę użytkownika. Zobaczysz jak prawidłowo zaprojektowane komponenty wraz z dobrze zaplanowanym UX pozwalają być niesamowicie produktywnym jednocześnie nie poświęcając jakości czy dobrej architektury aplikacji.
Jest to kurs dla osób które już pracowały z angularem i chciałyby wyjść poza pojedyncze techniki oraz poznać proces projektowania aplikacji w praktyce z uwzględnieniem najlepszych praktyk programistycznych oraz user experience. Zarówno w wariancie webowym jak i projektując pod urządzenia mobilne.
Angular 6, 7, 8+
W tej lekcji pokażę ci jak napisać testy dla usługi
oraz jak przetestować prawidłową komunikację pomiędzy usługą a
komponentem szczególnie gdy ta komunikacja odbywa się asynchronicznie
jak taki test na przykład zrobić przy użyciu observable mam tutaj wygenerowaną
usługę task serwis po prostu w katalogu projektu
i mam tutaj też w katalogu tym samym wygenerowany
testy przykładowe dla takiej usługi i teraz oczywiście
żeby przetestować tą usługę trzeba będzie ją stworzyć i będę miał tutaj kilka testów więc
znowu żeby nie powtarzać tych samych tych samych poleceń tworzących
tą usługę dla każdego testu zrobimy sobie znowu before each
czyli przed każdym testem utworzymy nową czystą intencję
tej naszej usługi i znowu nie będziemy robić tego ręcznie tylko dlatego że usługa
w przyszłości może mieć jakieś inne w zależności które
chcemy żeby angular wstrzyknął przygotował czyli nie będziemy testować swoje usługi w oderwaniu
tylko stworzymy sobie cały moduł testowy identycznie jak
przy komponencie tym razem jednak nie będziemy deklarować żadnych komponentów będziemy
definiować tutaj providers czyli tutaj konfigurację dependency injection dla naszej
usługi no i chcielibyśmy właśnie skonfigurować task service czyli
jeśli tutaj ktoś jakiś komponent inna usługa poprosiła task service no
to żeby taki tesk service został dla nas utworzony i teraz
jak można tutaj to przekazać sobie ten task service do testu
czyli sprawdził ten pierwszy test it should be
created czyli identycznie jak przy komponencie robiliśmy to wcześniej tu
sobie zrobimy test i teraz nie chcę tu robić jej ręcznie bo przez
new task service dlatego że w ten
sposób jeśli ta usługa wymaga innych usług trzeba by tu coś wstrzyknąć przez
konstruktor musiałnbym to samo robić ręcznie a ja nie chcę tego robić ręcznie chcę
żeby to zrobił angular i to jest bardzo fajna metoda pomocnicza dlatego
że mógłbym zrobić tutaj test bed get pobierać w
ten sposób za każdym razem tu gdzieś po tokenie pobierać
instancję jakiegoś elementu czy zrobisz task
service tu jeszcze alternatywnie jest opcja jeśli nie
znaleziono czyli można podać jakąś alternatywą wartość jeśli nie znaleziono to
jest jedna opcja druga opcja to jest taka specjalna funkcja inject
ja mogę cały test otoczyć funkcją inject która
jako pierwszy argument przyjmuje listę tokenów a drugi
funkcję do której ma je wstrzyknąć czyli mogę tutaj przekazać
listę usług komponentów dowolnych zależności które są skonfigurowane
w tym module i to będzie to będzie mi wstrzyknięty tutaj jako pierwszy
argument w tej funkcji czyli task service na przykład w ten sposób albo
service możemy tak to nazwać też okej
i jeśli by tu było więcej jakichś parametrów to one w tej samej kolejności jak
je zadeklarowałem tutaj pojawią mi się jako argumenty funkcji czyli jeśli teraz spojrzymy sobie na
serwis nie mamy tutaj żadnego typu więc jeśli jeszcze warto by tutaj
otypować sobie ten nasz serwis i teraz by nam podpowiadało tutaj wszystkie
pola metody tej klasy którą właśnie wstrzykujemy
i zaraz co my chcemy przetestować nasza
usługa task chciałbym żeby pozwalała mi pobierać listę
zadań którą możemy przekazać do komponentu aby je wyświetlił i jeśli
któreś zadania zmienię edytuję i kliknę zapisz to także chciałbym
żeby ten serwis tutaj ta usługa pozwalała właśnie obsłużyć
zapis no właśnie takiego taska nie będziemy tutaj komunikować się
z serwerem chciałbym zamockować tą usługę przygotować jakieś takie proste
api żeby ją spiąć z komponentem
i zobaczyć czy komplement prawidłowo komunikuje się z tą usługą czyli
po pierwsze sprawdźmy czy ta usługa się nam utworzyła czyli pierwszy test to będzie
expect serwis to
be czyli czy jest on prawdziwy czy został
utworzony jeśli otworzę tutaj testy no
to mamy na zielono 16 na 16 jednak jeśli pracuję nad tą
usługą tych testów jest bardzo dużo to oczywiście nie koniecznie musimy uruchamiać wszystkie
za każdym razem możemy tutaj znowu przełączyć żeby tylko te testy
się wykonywały które mamy tutaj i teraz jeden test się uruchamia
tutaj a pozostałe 15 jest pominięte tylko pamiętać o
tym żeby później to wyłączyć okej czyli usługa jest utworzona to
jedna rzecz z głowy teraz faktycznie testujemy działanie czyli
should powiedzmy fetch tasks
czyli jakaś funkcja jakieś
api do pobierania zadań i kolejny
test to będzie should safe task
i powiedzmy jakiś api powiedzmy że serwis no
i tu jest znowu żeby go utrzymać musiał go tutaj wstrzyknąć i znowu
jeśli chcemy wstrzykiwać praktycznie przy każdy teście
to możemy takie wstrzykiwanie także przenieść do before each
czyli mógłbym tutaj stworzyć let service typu
task service i to całe wstrzykiwanie przenieść
do sekcji before each inject
czyli to samo co tutaj mieliśmy i
tutaj zamiast testu po prostu service równa
się i tu musimy zmienić nazwę żeby ta nazwa nie kolidowała nam z tą bo inaczej
nie do tej zmiennej więc może tutaj napiszę task service
innej nazwy użyje i przypiszę do tej zmiennej ten parametr
który tu dostajemy okej service i teraz
w kolejnych testach nie muszę już tego injectować dlatego
że serwis powinien tutaj nam być dostępny z tej zmiennej zobaczmy
udało się i teraz w kolejnych testach mogę po prostu już
używać sobie tej zmiennej task service i tu właśnie stworzę nasze nowe api czyli
powiedzmy fetch all będzie
to funkcja która pobiera wszystkie zadania tutaj mi od razu
podpowiada edytor czy chciałbym zadeklarować jeśli wybiorę zadeklaruj można zrobić
to ręcznie można zrobić to automatycznie i wybiorę zadeklaruj jak widzisz tutaj automatycznie
w tym pliku w tej klasie pojawiło mi się tutaj metoda i z błędem
not implemented jeszcze raz spróbuj uruchomić powinno to ładnie pokazać
mi tutaj na czerwono że nie ma takiej metody muszę zapisać oba pliki
na pewno o i już mamy tutaj testy się nie udały ponieważ w
tym zadaniu mamy błąd method not implemented ale to nie szkodzi opiszmy
dokładnie cały test i wtedy zajmiemy się naprawą błędów implementacją żebyśmy najpierw
zrobili test później sprawili żeby on działał czyli napisali
implementację a później poprawili ewentualnie tutaj jakieś zmiany poprawki w
obu częściach czyli powiedzmy że fetch all właśnie
miałbyć typu observable czyli tu ja chciałem się zasubskrybować zobaczyć
czy dostanę jakieś odpowiedzi aby to działało musimy ustawić typ
observable any lub
observable task i tutaj nie mamy
typu task ja na chwilkę zajrzę do naszego komponentu task
list item i tutaj mieliśmy gdzieś specyfikację
naszego taska zobaczmy jeszcze nasz komponent no
właśnie tutaj interface task on znajduje się w tym miejscu i
warto go wyłączyć do następnego pliku dlatego że będziemy go współdzielić pomiędzy kilkoma różnymi
plikami ja sobie klikam żarówkę do osobnego pliku i utworzył
mi się plik task który zawiera ten nasz interfejs i
teraz w teście task service tutaj mi znowu podpowiada edytor
jeśli ci tu nie podpowiada to można zrobić to po prostu ręcznie fajnie
jak edytor takie coś wspiera taki refaktoring czyli podpowiada
co można tutaj przenieść co można zaimportować okej czyli mamy tutaj task i
teraz tu mogę zrobić subscribe i
tutaj dostanę obiekt
typu task czyli tablica zadań i teraz jak sprawdzić czy
to działa no najprościej po prostu tutaj wykonać expect
i sprawdzić czy task czyli to co dostaliśmy tu
equal nie to be tutaj żeby nie jechać to są te same obiekty tylko
to equal są takie same obiekty i tu stworzyć jakąś tablicę zadań
czyli powiedzmy id 1 2 3 tu
jeszcze mogę sobie podpowiedzieć że to jest task by mi wtedy ładnie podpowiadał typy
i teraz jak mam typ tu może mi właśnie podpowiedzieć title i czy
oczekuje jakiś testowych danych jednak tego nie dostanę bo po pierwsze
ta metoda zwraca zawsze error no a po drugie nizasymulowałem
tej metody i teraz ja nie chce faktycznie tu od razu ją implementować chcę
zasymulować działanie czyli muszę sprawdzić jak muszę
jakoś podstawić te dane że w momencie kiedy wykonam funkcje fetch all żeby
klasa task service faktycznie odwoływała się do jakiegoś źródła stamtąd
pobrała dane i ja muszę pod to źródło podstawić tej naszej
klasie dane żeby pobrała nieprawdziwe dane sprzed serwera tylko wybrała
jakieś fałszywe dane z tego źródła żebym mógł sprawdzić te fałszywe dane podstawione
zgadzają się z tym danymi których ja tutaj oczekuję powiedzmy więc
że nasza usługa task service będzie faktycznie tutaj bardzo prostą usługą
które od razu bezpośrednio próbuję pobierać takie dane z serwera
czyli tu powiedzmy ma http jest to http client
nie selenium web driver tylko
z pakietu tutaj angular common
http i powiedzmy jeśli tutaj ta metoda wykona
metodę get z pakietu http client no to spowoduje to zapytanie
do serwera i teraz my chcemy to przechwycić żeby zamiast
prawdziwego zapytaj do prawdziwego serwera żebyśmy mogli podłożyć podstawić
jakieś tutaj oszukane dane zmockowane i sprawdzić czy
funkcja prawidłowo zwróci to co jej podstawiliśmy i teraz jeśli chcemy inne tutaj
usługi testować no to prosta sprawa wystarczyło by do providerów dodać tą inną
usługę zrobić szpiega i zamockować wywołanie metody http
get z http client jest o tyle ciekawy że angular nam dostarcza jakby
gotowe narzędzia do pracy z http jeśli tutaj spojrzysz na http
common http tutaj jeszcze ma taki pakiet jak testing
i w pakiecie testing mamy http
klient testing module oraz http testing
controller tu są dwie fajne rzeczy po pierwsze tutaj w provider'ach nie
mogę podstawić prawdziwego modułu http dlatego że powodowały
to prawdziwe zapytanie do prawdziwego serwera z prawdziwą bazą danych tego nie chcemy
zamiast tego mamy właśnie ten testing module który
pozwala nam wszystkie zapytania przechwycić i zamockować czyli
postawić fałszywe odpowiedzi i teraz do podstawiania tych
fałszywych odpowiedzi do sterowania zapytaniami używa się ten http testing controller
jest to coś co pozwala nam zsymulować serwer w sensie przechwytywać
wychodzące requesty sprawdzać co się w nim znajduje a także
symulować odpowiedzi dla tych request'ów tak żeby nasz kod jemu
wydawało się że jest prawdziwym serwerem a tak na prawdę będzie rozmawiał z naszym testing
kontrolerem czyli musimy zasymulować komunikację z serwerem żeby tego użyć
oczywiście to normalna usługa muszę ją wstrzyknąć ja sobie tutaj zdefiniuję zmienną
controller typu http testing controller
i podobnie jak nasz serwis tu sobie go wstrzykniemy
czyli oprócz serwisu zrobimy jeszcze http controller
i controller równa
się http controll czyli to wstrzykniemy
tutaj do tej lokalnej zmiennej wstrzykujemy nasz controller teraz jak taki kontroler
działa jeśli ja tutaj robię fetch all to robiąc fetch all
ja oczekuję że ta nasza usługa task serwis zrobi zapytanie do serwera
więc jak robiąc tutaj fetch all na
naszym kontrolerze mogę powiedzieć że oczekuję żadnych tutaj
zapytań oczekuję jednego zapytania lub oczekuję specjalnego
zapytania które pasuje do jakiegoś wzorca mogę też sprawdzić
czy wszystkie zapytania zostały przechwycone czy nie zostało żadnych nieoczekiwanych
tutaj nie ma nieoczekiwanych zapytań do serwera zacznijmy więc może od sprawdzenia czy mamy
request tutaj potrzebujemy url tu podam tasks
na przykład przykładowy url tu opis czyli
coś tam się w błędach wyświetli czyli na przykład tasks api
and point okej i
takie coś zwraca nam obiekt typu test request czyli zobaczmy
sobie const request i
teraz request pozwala nam zanalizować zapytanie czyli
jeśli faktycznie było zapytanie to zapytanie będzie pasowało
do tego wzorca tutaj możemy zobaczyć szczegóły takiego zapytania na
przykład zobacz tu właśnie request zobaczysz sobie ciało
requesta nagłówki metoda parametry i tak
dalej czyli możemy sobie podejrzeć takie zapytanie i teraz
zobaczymy co testy teraz na to okej
tutaj testy nie zadziałają bo mamy ten nasz błąd
nie może wstrzyknąć http client do naszej usługi task service
no właśnie to nie do providerów teraz
oczywiście moduł więc do importów tutaj
mój błąd zobaczmy teraz w method not implemented okej
spróbujmy tutaj wykonać zapytanie this http
get tasks okej tutaj
mu się typy nie będą zgadzały bo otrzymujemy taska więc na chwilkę to zmienię na any
i mamy tutaj sukces ja spróbuję tutaj zobaczyć jeszcze co się pojawiło
w tym request to jest
jedna opcja do debugowania z console logiem możemy także mając tutaj request na
przykład debugger i jeśli mamy
otwarte tutaj okno jasmine nie możemy tu uruchomić debuggera
dlatego że to jest nakładka jeśli chcemy faktycznie zobaczyć co się dzieje w
środku w naszych testach to tutaj klikając debug możemy jak widzisz bez tej
tego całego całej nakładki tylko wejść faktycznie uruchomić się w
okienku testów i tutaj mamy konsole mamy jak widzisz wszystkie testy i
jak odświeżę z otwartym narzędziem deweloperskim to nam się elegancko to
zatrzyma w teście powiększę tutaj trochę konsolę
żebyśmy widzieli jak widzisz
jest to nasz test nasz kod źródłowy timescript i mogę sobie przejrzeć właśnie
request tutaj widać nagłówki zapytanie get nie mamy
żadnych parametrów url task czyli faktycznie metoda
nasza fetch all wykonała zapytanie i przechwyciliśmy
to zapytanie i teraz co możemy jeszcze zrobić możemy
zanalizować to zapytanie możemy sprawdzić czy ono faktycznie istnieje
jeśli on mi się pomylił i wpisał inny url zobaczmy
testy tu trzeba faktycznie jeśli mamy zablokowane
to muszę zwolnić blokadę i spójrz
spójrzmy sobie expected matching request for criteria task api endpoint
found none czyli dokładnie ten nasz opis tego endpointa tutaj
mamy w będzie że ten endpoint tutaj nie było request na ten endpoint
a był jeden oczekiwany czyli jak widzisz on sprawdza czy faktycznie to
api wykonuje wszystkie zapytania do serwera których oczekujemy co możemy
jeszcze zrobić możemy faktycznie zasymulować jakąś zwracana wartość czyli
powiedzmy że potrzebujemy tych tasków więc jak mam nasz request możemy
zrobić tak zwany flush event lub error
czyli możemy zasymulować błędną odpowiedź serwera na przykład
tutaj błąd połączenia z siecią ale i tak dalej możemy pojedynczy
event na przykład jeśli symulujemy pobieranie pliku albo upload pliku i chcemy mieć wiele
eventów na przykład o postępie pobierania ile procent się pobrało możemy to symulować jeśli chcemy
całą odpowiedź od razu zwrócić to mamy flash tutaj zobacz
musimy przekazać praktycznie no właśnie odpowiedź body czyli
tutaj właściwie mógłbym mieć dokładnie to samo co tutaj czyli listę naszych tasków
bez tych nawiasów czyli tu przekazuję odpowiedź z serwera zasymulowaną
okej success i teraz
uwaga bo zobacz jeśli zmienię tutaj na przykład test task 2
to zobaczmy okej udało się porównuje jak widzisz title
test to jest teraz 2 tu equal test task czyli faktycznie to działa tutaj
metoda subscribe wychwytuje odpowiedź
tutaj z serwera czyli po pierwsze sprawdzamy że oczekuje odpowiedzi
po tym jak wysłałem zapytanie nie przed a
następnie jak mam zapytanie mogę na nie odpowiedzieć czyli mogę
tutaj zwrócić i jakieś wyniki jeśli one się zgadzają to ten test
nam zadziała i sprawdzi czy zasymulowane zapytania do
serwera zwróciło faktycznie poprawną odpowiedź jeśli tutaj chcemy mieć
poprawne typy to fajną rzeczą jest to że metoda get jest tutaj generyczna ja mogę
przekazać typy zwracania odpowiedzi i wtedy upewnić się że to co wyjdzie z get będzie
pasowało tutaj do naszego typu okej i zaraz zobaczmy jeszcze
i mamy tej success i jeśli zrobisz
kolejną metodę czyli save task może zrobić zupełnie
analogicznie czyli też tasks service w
tym miejscu tym razem nie fetch all tylko właśnie na przykład save i
tu mogę zasymulować jakiegoś taska czyli też sobie wymyślę jakieś const task
zróbmy go jeszcze typu task
żeby mi tu pilnował przekażemy task do środka
i możemy zasubskrybować na odpowiedź i
w odpowiedzi no właśnie mógłbyś sprawdzić czy się udało go
zapisać ale przedtem sprawdzimy czy faktycznie było
zapytanie do serwera czyli sprawdzamy na przykład expect
one i tutaj jest jeszcze kilka możliwości po do
expect one mogę dać url i opis zwykłego geta robić
bo mogę parametry opis mogę funkcje
match'ującą przekazać to dostanie request i mogę sprawdzić czy to jest fałsz czy
prawda tutaj możemy też
tak zwane obiekt request match i możemy
też zrobić to naszym tutaj match i
match oczekuję tutaj no właśnie obiekt typu request match lub
funkcja spróbujmy z obiektem jak widzisz tutaj mamy opcję method czyli
mogę powiedzieć że to jest post bo chcemy zapisać naszego taska i url
powiedzmy także tasks czyli jak widzisz mogę oczekiwać też różnych
metod różnych szczegółów mógłbym też zrobić funkcję która dostaje tutaj request
cały i wtedy dokładnie powiedzieć wszystko url parametry i tak dalej
jest wiele możliwości porównywania i powiedzmy że odpowiemy
na request czyli request flash coś
tu poszło nie tak test request czemu
tu mamy tablice no
tak bo to znajdzie wiele odpowiedzi spróbujmy expect
one spróbujmy teraz flush no
właśnie expert one ma te same parametry przyjmuje ale właśnie wymaga jednego konkretnego że
tylko jeden match jak widzisz pozwoli znaleźć wszystkie wysłane
które pasują do jakiegoś wzorca nam wystarczy jeden więc znowu zrobimy flush
i powiedzmy że no właśnie tutaj co
mamy możemy tylko body przesłać czyli będzie to nasz tasks powiedzmy
zapisany ale oprócz tego mam tu jeszcze opcję i możemy
dodatkowo przekazać na przykład status że tu będzie 201 na przykład czyli utworzono
zadanie czy powiedzmy że wysyłam go no właśnie wyszedł bez
id a będę oczekiwał że przyjdzie do nas z
id czyli utworzymy tutaj tasks
id na przykład w ten sposób czy tu jest task
częściowy
task bez id przekazujemy do środka ok
i w subscribe expect task
to be defined
na przykład i expect task kropka id
to be defined na przykład w ten sposób i
teraz znowu zadeklaruję sobie metodę bo jej nie ma mam błąd że save nie jest function
czyli deklarujemy metodę tu oczywiście będę narzekał że jest niezdefiniowane
typ zwracany tym razem to będzie nie any tylko
będzie to jeden task zapisany a przyjmujemy tu jak ten typ sobie obeszliśmy tutaj
partial task czyli task który może nie mieć pewnych pól może nie mieć id
i odpowiednio return this i
nie get tylko post czyli http post bo chcemy
dopasować do tego typu tutaj które mamy w tym miejscu post status
201 to
właśnie można by jeszcze by sprawdzić test status ale to sobie już podarujemy
czyli tak samo tasks i tu przekaże
nasz task do zapisania i
typ się oczywiście nie zgadza dlatego że w przy poście identycznie też
mogę określić jaki jest oczekiwany zwracany typ serwera
zapiszę zobaczymy teraz jeszcze jakiś błąd status
test status text is required when setting a custom status
no właśnie status
text created czyli udało
się utworzyć zobaczmy i mamy sukces czyli jak widzisz analogicznie
mamy metodę save która już ma jakieś przekazywane body
jakieś parametry też mogliśmy sobie je porównać i
tu przy expect one mamy tylko
method url gdybyśmy chcieli sprawdzić body
no to tutaj niestety musimy korzystać z tej bardziej zaawansowanej
metody czyli trzeba by przekazać tutaj funkcję i sprawdzić faktycznie czy zawiera
body czyli zrobić tu request i
sprawdzić tutaj odpowiednio czy method się zgadza czyli expect czyli
sprawdzić czy request breakfast method
równa się post request
body równa się task
tutaj nie przecinek and to trzeba zwrócić żeby powiedzieć
czy to jest prawda czy fałsz robimy w ten sposób sprawdźmy jeszcze faktycznie
czy to na pewno działa okej
czyli jak widzisz możesz w bardziej zaawansowany sposób sprawdzić czy ten request jest
poprawny czy zawiera wszystkie potrzebne informacje okej i
teraz jeśli mamy taką przetestowaną usługę i chcielibyś spiąć
ją z jakimś komponentem czyli powiedzmy nasz task service
to jest coś co jest wymagane na przykład w komponencie task
list component task list component i
tak list component spec i powiedzmy
że component chcielibyśmy wstrzykiwać do niego usługę jeśli on tu
będzie wymagał naszego powiedzmy
task serwisu i zrobimy żeby te testy
też się uruchamiały to się może pojawić trochę problem
no właśnie wymaga on tutaj task serwisu
a task service wymaga http clienta i
jest to problem dlatego że nie chcemy żeby nasz task list próbował
ładować cały http client dlatego co możemy
zrobić tutaj w providerach chcemy zrobić
stap czyli chcemy podmienić tą usługę na coś co wygląda jak
usługa ale nią nie jest czyli provide niby
chcemy wziąć task service ale tak naprawdę w jego
miejsce chce wstrzyknąć jakiś mock czy tutaj
jasmine pozwala mi stworzyć szpiega albo
cały obiekt szpiega i obiekt szpiega ma tutaj różne ciekawe
opcje mogę nadać mu nazwę na pewno i metody
zdejmę mu nazwę task service i
metody będzie to tablica lub
obiekt spróbujmy z tablicą i potrzebuję tych dwóch metod naszych
czyli będą to save
i fetch all fetch all
no okej i teraz do naszych testów musimy wstrzyknąć tą usługę task serwis
czyli tak jak robiliśmy to wcześniej po prostu do komponentu
should fetch
data from service tu robimy inject
dlatego że potrzebował będę właśnie tego naszego task
service i tutaj
ja oszukam troszeczkę bo powiem że to jest tego typu mimo że nie
jest chcę żeby było tutaj podpowiadał mi właściwe
metody na tej usłudze naszej service ale
te metody nie będą prawdziwe metody tej usługi tylko będą tymi zmockowanymi tutaj już
szpiegami czyli spróbujemy wywołać fetch all
no właśnie mogę powiedzieć że jest to task service albo
jeszcze lepiej mogę powiedzieć że to jest szpieg
typu task
service i wtedy nasza metoda fetch all ma wszystkie parametry szpiega czyli
w ten sposób mogę sobie zaszpiegować te odpowiednie informacje czyli
powiedzmy że oczekuję że nasza metoda fetch all
to have been called została wykonana ale nie
od razu tylko po tym jak wykonam metodę powiedzmy
fetch data
naszym komponencie zadeklaruj metodę
fetch data i metoda fetch data właśnie ma skorzystać z usługi czyli
service fetch all subscribe
data i powiedzmy że tu będą nasze zadania tasks i
nasze data przy przypiszemy tutaj do this tasks to
się równa data data jest typu task tu się wszystko
zgadza zobaczmy
testy fetch data i czy funkcja była wykonana
funkcja była wykonana ale nie udało mu się zrobić
subscribe tutaj bo oczekiwał że coś dostanie z powrotem nie chcę pobrać oryginalnej
funkcji dlatego tutaj nasz fetch all przygotjemy
go żeby zasymulował jakąś odpowiedź czyli and call fake
return value i tu stworzymy sobie wartość
czyli jakiś operator of z ng
tak i zasymulujemy tablice
jakiś tam zadań czyli to będzie as task
okej tak jak wcześniej to robiliśmy
czyli tu podpowiemy sobie id i ten 2 3 title
test i sprawdzimy czy to have been called
i możemy sprawdzić co zwróci nasze fetch data mianowicie
po fetch data możemy sprawdzić czy komponent tasks
ma dokładnie te same tutaj
obiekty tą samą tablicę zadań okej sukces
sprawdźmy jeszcze czy ten test na pewno nie jest dziurawy zmienię na dwójkę
i dokładnie sprawdzę to co potrzebujemy czyli jak widzisz wspinając
komponent z usługą nie chcemy używać prawdziwej usługi chcemy pod
tą usługę wsadzić coś co pozwala przechwycić symulować właśnie
jej api czyli przesłać jakichś szpiegów pojedynczych szpiegów lub cały tutaj spy
object który pozwala zasymulować to natomiast wstrzykując to ja
mogę określić jakiego typu ja oczekuję że on myśli że wstrzykuje mi
task service a wstrzykuje mi szpiega ja sobie w typach oznaczam że to jest szpieg
dzięki temu właśnie mogę tutaj mockować odpowiedzi mogę
sprawdzać czy funkcja została wykonana mogę sprawdzać jakie parametry funkcja zwróciła
jest jakaś podstawa testowania właśnie relacje między usługami
byśmy też testowanie usług i testowanie właśnie usług
które wymagają innych usług innych modułów nawet gdy te moduły pochodzą właśnie
z angulara i testowanie odpowiedzi zapytań do serwera więc
to pozwala jakby zamknąć jakby podstawy testów jednostkowych
o testach będziemy jeszcze rozmawiać w kolejnych lekcjach
zająłem się jednak architekturą zajmiemy się jednak praktycznym podejściem do
budowania aplikacji na troszkę większą skalę niż pojedyncze
komponenty i usługi ale o tym wszystkim już w kolejnych lekcjach więc do zobaczenia