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

JS . Testowanie funkcji strzałkowych.

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
+1 głos
654 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 (606,240 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 (606,240 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 (606,240 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 (606,240 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 560 wizyt
0 głosów
0 odpowiedzi 216 wizyt
pytanie zadane 23 kwietnia 2023 w C# przez Badur Nowicjusz (120 p.)
+1 głos
1 odpowiedź 267 wizyt
pytanie zadane 2 grudnia 2022 w C i C++ przez pasjonat_algorytmiki Pasjonat (19,540 p.)

93,194 zapytań

142,206 odpowiedzi

322,051 komentarzy

62,518 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 3053p. - dia-Chann
  2. 2998p. - Łukasz Piwowar
  3. 2993p. - Łukasz Eckert
  4. 2970p. - CC PL
  5. 2930p. - Tomasz Bielak
  6. 2907p. - Łukasz Siedlecki
  7. 2890p. - rucin93
  8. 2801p. - Adrian Wieprzkowicz
  9. 2645p. - Mikbac
  10. 2485p. - Marcin Putra
  11. 2461p. - Michał Telesz
  12. 2418p. - Michal Drewniak
  13. 2371p. - Anonim 3619784
  14. 1733p. - rafalszastok
  15. 1650p. - Mariusz Fornal
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...