• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

JS . Testowanie funkcji strzałkowych.

Object Storage Arubacloud
+1 głos
461 wizyt
pytanie zadane 15 kwietnia 2017 w JavaScript przez rot18 Początkujący (350 p.)

Zacznijmy od prostego przykładu:

function foo() {
  eventManager.on('foo', () => {
    console.log('foo');
  }
}

Prosta funkcja, ale już pojawia się problem. Jak napisać do tego testy jednostkowe  ?

describe('foo') {
  it(' wywołuję eventManager.on z parametrem funkcji, która wywołuje console.log z parametrem tekstowym', () => {
  .. 
  } );
}

Jak widać pojawia się słowo "która" wskazujące, że nie testujemy naprawdę tego co chcieliśmy. Gdybyśmy przepisali to na dwie normalne funkcje, byłoby znacznie prościej.

function foo1() {
  eventManager.on( 'foo', foo2);

function foo2(){
  console.log('foo');
}

Testy:

describe( 'foo', () => {
  it( 'wywołuje eventManager.on z parametrem foo2', () => {
  ..
  }
}
describe( 'foo2', () => {
  it( 'wywołuje console.log z parametrem tekstowym, () => {
  ..
  }
}

Jak widać znacznie prościej. Czy z tego powodu że nie da się napisać normalnych testów jednostkowych do funkcji strzałkowych powinno się ich unikać ?

komentarz 15 kwietnia 2017 przez ScriptyChris Mędrzec (190,190 p.)
edycja 15 kwietnia 2017 przez ScriptyChris

Nie miałem jeszcze przyjemności pisać testów (shame on me frown), więc nie mam pewności, ale zakładam że do przetestowania funkcji musisz mieć jej referencję. Natomiast funkcje strzałkowe są funkcjami anonimowymi użyłeś funkcji strzałkowych jako anonimowych, do których referencji nie masz, bo są tworzone dynamicznie ("w locie") w momencie ich użycia. Jeśli to możliwe, to po prostu zamień funkcje anonimowe na normalne funkcje i postępuj tak jak z foo2.

3 odpowiedzi

+1 głos
odpowiedź 15 kwietnia 2017 przez Comandeer Guru (600,810 p.)

A nie wystarczy nałożyć szpiega na console.log i odpalić zdarzenie foo, a następnie sprawdzić, czy console.log zostanie odpalone? Przecież o to nam chodzi, niekoniecznie o to, jak dokładnie to jest robione. Zadaniem jest sprawdzenie, czy konkretne zdarzenie wywołuje konkretną reakcję.

Niemniej tak, przy testowaniu listenerów o wiele lepiej całkowicie odrzucić funkcje anonimowe i przenieść się na normalne.

komentarz 16 kwietnia 2017 przez rot18 Początkujący (350 p.)
Twój sposób byłby dobry na test integracyjny. Jednak w przypadku testów jednostkowych nie chcemy testować co robi EventManager. Może on tylko przechowywać funkcje, a nie je wywoływać. Zadaniem foo jest jedynie subskrypcja zdarzenia odpowiednim callbackiem i tylko to powinno zostać przetestowane.
komentarz 16 kwietnia 2017 przez Comandeer Guru (600,810 p.)
To po co pytasz, skoro wiesz lepiej…?

Jeśli koniecznie chcesz przetestować listener w izolacji, to wydzielasz go do osobnej funkcji – tyle.
komentarz 16 kwietnia 2017 przez rot18 Początkujący (350 p.)
Właśnie nie wiem nic. Raz skrupulatnie testujesz zwyczajne wywołania funkcji w całkowitej izolacji (jak w przypadku loggera), później chciałbyś uwalić całą logikę do jednego testu.

Na początku chciałem testować tylko funkcje, które rzeczywiście zawierają jakąś logikę. Przez twoje dziwaczne podejście do loggera zacząłem testować wywołania zwykłych funkcji :P
komentarz 16 kwietnia 2017 przez Comandeer Guru (600,810 p.)

No bo w przypadku loggera nie da się w sumie napisać jakichś bardziej sensownych testów. Tam logika sprowadza się do tego prostego faktu, że pod spodem są wołane odpowiednie metody console i to też jest testowane.

+1 głos
odpowiedź 17 kwietnia 2017 przez Strategiusz Dyskutant (9,220 p.)
Czytałem artykuł, w któym ktoś odradzał używanie anonimowych funkcji. Jednym z argumentów była trudność ich testowania. Poza tym trudny do czytania kod, niemożność ponownego użycia i brak nazwy, która by opisywała co dana funkcja robi.
komentarz 17 kwietnia 2017 przez kap Stary wyjadacz (11,620 p.)
edycja 18 kwietnia 2017 przez kap

Tu odpowiedź brzmi jak zwykle: "to zależy" - jak autor artykułu odradza funkcje anonimowe w ogóle, to pisze bzdury. Funkcje anonimowe (najlepiej arrow) są super przydatne w wielu przypadkach i niekoniecznie zminiejszają czytelności lub utrudniają sensowne testowania.

komentarz 19 kwietnia 2017 przez Strategiusz Dyskutant (9,220 p.)
Pewnie tak. Sam widzę, że anonimowe funkcje w JS są często używane tak jak bloki w Ruby i czasem nie ma sensu tworzyć ich osobno. Wygodniejsze są wtedy "arrow", bo nie mają własnego this. Anonimowe callbacki pozwalają też przesłać niestandardowy argument.
0 głosów
odpowiedź 15 kwietnia 2017 przez kap Stary wyjadacz (11,620 p.)
No a napisz te testy dla drugiego przypadku, który niby rozwiązuje problem, bo wg mnie nic tam nie zmieniłeś co by ułatwiło przetestowanie.

Poza tym testowanie implementacji to droga do nikąd.
komentarz 16 kwietnia 2017 przez rot18 Początkujący (350 p.)

Znacznie prostsza jest forma testów, w której testujemy wszystko po kawałku zamiast robić jeden test w formie: "funkcja foo wywołuje funkcje z parametrem funkcji, która wywołuje funkcje, która robi coś tam bla bla bla"

Co do formy testowania, zobacz sobie testy loggera z książki Comandeera. Jedyne co się w nich testuje to "czy funkcje w JavaScripcie działają poprawnie". Kiedyś nawet zapytałem o to (z innego konta bo zapomniałem hasła). O dziwo Comandeer uznał taką formę testów za całkowicie poprawną.

 

komentarz 16 kwietnia 2017 przez Comandeer Guru (600,810 p.)

O dziwo Comandeer uznał taką formę testów za całkowicie poprawną.

A Ty mi nie podałeś żadnego argumentu, dlaczego niby nie jest poprawna  ¯\_(ツ)_/¯

Skoro chcemy przetestować, czy logger faktycznie loguje (czyli wywołuje odpowiednie funkcje), to… sprawdza się, czy wykonuje odpowiednie funkcje. Nie sprawdzam, czy "funkcje działają" tylko, czy działają w tym konkretnym kontekście w ściśle określony sposób. 

komentarz 17 kwietnia 2017 przez kap Stary wyjadacz (11,620 p.)
edycja 18 kwietnia 2017 przez kap

No ale pokaż jak byś napisał te testy, bo tak na sucho dyskutujesz. Tam bez zmiany funkcji foo nie przetestujesz tego w sposób w jaki byś chciał.

Po drugie - powtarzam, testujesz tam implementację - zmienisz implementację to musiasz zmieniac testy - bezsens. O wiele lepiej przetestować sam zamierzony efekt, w tym przypadku tak jak @Comandeer proponuje, bo funkcja nic nie zwraca i trzeba uzyć spy na console.log

 

Testuj gdzie tylko możesz funkcjonalność systemu a nie rzeczy, które mogą się zmienić przy refaktorze. Wtedy się okazuje, że testy zaczynają ułatwiać refactor, zamiast w nim przeszkadzać.

komentarz 23 kwietnia 2017 przez rot18 Początkujący (350 p.)
Dobra już wszystko rozumiem. Po prostu napisałem herezje bo nie jestem doświadczony w testowaniu.

Podobne pytania

0 głosów
0 odpowiedzi 466 wizyt
0 głosów
0 odpowiedzi 194 wizyt
pytanie zadane 23 kwietnia 2023 w C# przez Badur Nowicjusz (120 p.)
+1 głos
1 odpowiedź 166 wizyt
pytanie zadane 2 grudnia 2022 w C i C++ przez pasjonat_algorytmiki Pasjonat (19,540 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...