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

testowanie funkcji w JEST

Object Storage Arubacloud
0 głosów
276 wizyt
pytanie zadane 7 września 2021 w JavaScript przez Olivier Mazur Użytkownik (680 p.)

Czesc chce napisac swoj test, ale niestety nie przechodzi prosze o pomoc..
Mam taka funkcję:
https://codepen.io/olivier-mazur/pen/RwgoEdg
w dataStore mam dwie własciowosci: isBlocked oraz actionId
Napisalem taki test, ale nie przechodzi.

 it("should block all Actions", () => {
    // given
    const webSocketServiceMock = spyOn(wsServiceMock, "send");
    // when
    service.blockAllActions();
    // then
    expect(webSocketServiceMock).toHaveBeenCalledWith(
      "/block",
      1
    );
  });

Mam taki błąd:
Expected spy send to have been called with [ '/block, '1' ] but it was never called.

1 odpowiedź

0 głosów
odpowiedź 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)

A czy service.blockAllActions używa wewnątrz mocka webSocketServiceMock? Bo w pokazanym kodzie po prostu tworzysz zamockowaną funkcję, którą przekazujesz do expect, ale ona nie jest nigdzie wołana. Podobnie z wsServiceMock - czy on jest gdzieś użyty w implementacji?

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
tak było to juz zaimplementowane, juz wczesniej i to działa. Potrzebujesz jakis danych? Bo ja juz pomysłow nie mam na to
komentarz 7 września 2021 przez Wiciorny Ekspert (270,230 p.)

@ScriptyChris, generalnie mock to obiekt, więc nie można mokować funkcji, a jedynie obiekt dla funkcji tak precyzyjnie.
Moim zdaniem tutaj będzie problem taki, że nie wiemy nawet czy zamokowany jest sam servis.

komentarz 7 września 2021 przez Wiciorny Ekspert (270,230 p.)
edycja 7 września 2021 przez Wiciorny

tak, ale co przechodzi :)? wywołanie send, czy to że weryfikujesz "called- na webSocketServiceMock" :) a nawet nie na nim tylko wywołanie metody.

Bo ja wiem i starcza w logi spojrzeć :) jak sobie dodasz logera albo masz w środowisku

bo prymitywnie test zwróci prawde dla takiej bzdury nawet 

myCollection.size();
        myCollection.size();
        verify(myCollection,times(2)).size();

druga rzecz, to nie przechodzi bo send nie zostanie wykonane jesli metoda nie przyjmuje argumentów, 
 

 send: (destination, message) => {}

bo oczekuje parametru, a bez parametru nie wykona sie .

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
przywrócone 7 września 2021 przez Olivier Mazur
hm tylko nie rozumiem dlaczego gdy otwiera mi się w przeglądarce karma to tamten test jest na zielono, a ten moj na czerowno ..
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)

@ScriptyChris, generalnie mock to obiekt, więc nie można mokować funkcji, a jedynie obiekt dla funkcji tak precyzyjnie.

@Wiciorny, Jest posiada API do mockowania funkcji.

@Olivier Mazur, w teście "should block the Action" metoda blockTheAction wywoła this.wSService.send, gdy przekażesz tam cokolwiek typu truthy (a w teście przekazujesz "1"). Natomiast test "should block all Actions" dla  funkcji blockAllActions korzysta z tablicy this.dataStore.blockedActions, na której są filtrowane jakieś rzeczy. Sprawdź więc, czy w trakcie testu filter coś zwraca, bo jeśli jest to pusta tablica, to forEach, w którym jest wołany this.wSService.send, może w ogóle się nie wywoływać.

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
Wiesz może co musze zrobić skoro parametru tam nie przekazuje?
komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
Jak mogę to sprawdzic? Jestem zielony w testach i tak naprawde jest to moj pierwszy test i mam wrazenie, ze zostałem wrzucony na głęboką wodę. Mam to zapisać jak w zwykłej funkcji js?
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)

Ja bym najpierw wstawił console.log, żeby się upewnić, że pętla wołająca zamockowaną metodę send działa.

  blockAllActions() {
    const filteredActions = this.dataStore.blockedActions
      .filter((blockedAction) => !blockedAction.isBlocked);
   
    console.log('filteredActions:', filteredActions);

    filteredActions.forEach((blockedAction) => {
        this.wSService.send("/block", blockedAction.actionId);
      });
  }

Jeśli log pokaże nie-pustą tablicę, to wtedy winny może być mock.

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
Sprawdziłem i są elementy w tablicy
komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)

@Wiciorny, jak mogę ominąc to, zeby nie przekazywać parametru ? 

komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)

@Olivier Mazur, a jak logniesz this.wSService.send wewnątrz forEach to co pokaże konsola?

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
jak zamienie:

// expect(webSocketServiceMock).toHaveBeenCalledWith("/app/actionBlock", "1");

  expect(webSocketServiceMock).toHaveBeenCalledTimes(0);

To wtedy test przechodzi i jest na zielono.. nie wiem czy to cos pomoże
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)

Nie rozumiem do czego odnosi się kod w tym komentarzu (wygląda na implementację metody send, ale w teście przecież tworzysz z niej mock, więc implementacja nie powinna mieć znaczenia). Pytałem co wyświetli konsola, jeśli wypiszesz w niej referencję funkcji (w kontekście testu - mocka funkcji):

  blockAllActions() {
    this.dataStore.blockedActions
      .filter((blockedAction) => !blockedAction.isBlocked)
      .forEach((blockedAction) => {
        console.log('mock fn:', this.wSService.send);

        this.wSService.send("/block", blockedAction.actionId);
      });
  }

 

expect(webSocketServiceMock).toHaveBeenCalledTimes(0);

To wtedy test przechodzi i jest na zielono.. nie wiem czy to cos pomoże

Błąd z Twojego pytania odnosi się do tego, że zamockowana funkcja nie była wywołana, a Ty oczekujesz że zostanie wywołana z konkretnymi parametrami. Powyższy zapis sprawdza, czy funkcja nie została zawołana, co w kontekście Twojego problemu jest ok, ale generalnie taki test da Ci fałszywie pozytywny wynik, bo ta funkcja powinna zostać wywołana z określonymi parametrami.

Więc nie, użycie toHaveBeenCalledTimes z parametrem 0 nie rozwiązuje problemu, a wręcz szkodzi, ponieważ test nie spełnia swojej roli - chyba, że jego zadaniem jest sprawdzić, że implementacja faktycznie nie działa.

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
no własnie ten console to wyswietlił
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)

Ah, więc nie jest to mock, tylko faktyczna referencja do funkcji. Spróbuj wyłączyć/zignorować wszystkie testy, poza tym jednym i sprawdź, czy problem występuje. Możesz też ten jeden zdefiniować jako fit zamiast it, co wymusi wykonanie tylko jego.

komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
Mam ten sam błąd

Expected spy send to have been called with [ '/block', '1' ] but it was never called.
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)
A jak uruchomisz tylko test "should block the Action", to on nadal przechodzi?
komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
tak, ten przechodzi
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)
Może przed tym niedziałającym testem jest wykonywane jakieś czyszczenie mocków?
komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
nie ma
komentarz 7 września 2021 przez ScriptyChris Mędrzec (190,190 p.)
To, szczerze mówiąc, nie wiem o co chodzi.
komentarz 7 września 2021 przez Olivier Mazur Użytkownik (680 p.)
send sie nie wykonuje bo metoda service.blockAllActions(); nie przyjmuje parametrów, nie wiem czy mogę jakos to ominąc
komentarz 8 września 2021 przez Olivier Mazur Użytkownik (680 p.)
teraz sprawdziłem i faktycznie w niektorych przypadkach moze występowac pusta tablica po filtrowaniu
komentarz 8 września 2021 przez Wiciorny Ekspert (270,230 p.)

@Olivier Mazur, to samo napisałem na samym starcie tego długiego wywodu, 

Podobne pytania

+1 głos
3 odpowiedzi 463 wizyt
pytanie zadane 15 kwietnia 2017 w JavaScript przez rot18 Początkujący (350 p.)
+2 głosów
0 odpowiedzi 201 wizyt
pytanie zadane 3 grudnia 2021 w JavaScript przez lzrd Nowicjusz (160 p.)
0 głosów
0 odpowiedzi 124 wizyt
pytanie zadane 3 sierpnia 2018 w JavaScript przez dzawadzki Nowicjusz (120 p.)

92,584 zapytań

141,433 odpowiedzi

319,668 komentarzy

61,966 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!

...