Mocki, Mocki wszędzie... Jak się ich pozbyć?

Поделиться
HTML-код
  • Опубликовано: 25 окт 2024

Комментарии • 23

  • @lenkowski-net
    @lenkowski-net 5 месяцев назад

    Powodzenia w rozwijaniu kanału! Im więcej dobrej treści tym lepiej 🔥🔥🔥

  • @Rafal.Kiedrowski
    @Rafal.Kiedrowski 5 месяцев назад +1

    dobre to, ku.wa! 😉

  • @doogiPL
    @doogiPL 5 месяцев назад

    Absolutnie zgadzam się z idea redukcji mocków, które konczy sie najczęściej testami implementacji, a nie zachowania. Zastanawia mnie jednak czemu nie rozwinąleś mocniej tematu innych typów test doubles, ktorymi mozna osiagnac podobny cel, czyli stubami? Czy są argumenty, które powodują, że moga one nie spełniać Twoich wymagań co do testowania wyłącznie zachowania?

    • @adambanaszkiewicz
      @adambanaszkiewicz  5 месяцев назад

      Mam w planach odcinek poświęcony wszystkim rodzajom dublerów testowych :) Tutaj chciałem się skupić tylko na problemie mocków i jak je zastąpić :)

  • @kosaa03
    @kosaa03 3 месяца назад

    Pojawiło mi się kolejne pytanie. A co jeśli mamy implementację repo InMemoryProductRepository, a na encji mamy pole $version do optimistic lockingu i dodatkowo w serwisach jawnie korzystamy z transakcji. Czy te dwie rzeczy też muszą być "odpowiednio" obsługiwane przez tą implementację InMemory? Czy wtedy kod tego repozytorium nie będzie zbyt skomplikowany?
    Jak to wygląda w rzeczywistym projekcie?

    • @adambanaszkiewicz
      @adambanaszkiewicz  3 месяца назад +1

      Bardzo dobre, nietrywialne pytanie :) Najpierw zadałbym pytanie, czy obsługa optimistic lockingu jest biznesowa czy techniczna. Jeśli techniczna, to nie przejmowałbym się tym w implementacjach InMemory. To mają być proste implementacje, implementujące interfejs. Sam OL można przetestować na co najmniej dwa różne sposoby, i tego bym się trzymał. InMemory bez $version, a integracyjnie przetestować czy dane repo poprawnie obsługuje wersjonowanie.
      Natomiast gdy OL jest biznesowy, to warto w tedy to bardziej uwydatnić, ale już nie tylko przez $version w encji, ale przez interfejs Repozytorium, rzucane wyjątki, ich obsługę, ewentualnie jeśli potrzeba to nawet nazwy metod. W tedy powinieneś przetestować OL jako część Twojego kontraktu. Tutaj wchodzimy na grząski grunt, nie mając wiedzy biznesowej więc na tym się zatrzymam :D
      Pytanie ma o wiele więcej niuansów, zakładam, że mogę nie wiedzieć czegoś co mogłoby wpłynąć na moją odpowiedź, więc poproszę byś nie traktował tego jako wyroczni, jeśli popełniłem błąd przez niewiedzę o Twoim przypadku :)

    • @kosaa03
      @kosaa03 3 месяца назад

      ​@@adambanaszkiewicz Nie mnie oceniać czy popełniłeś błąd czy nie :D Dzięki! Załapałem Twój sposób myślenia, mam nadzieję :)
      Biznesowe rzeczy - unitowo i wtedy OL tak; Technicznie - proste testy integracyjne dla OL
      Czy do transakcji i innych podobnych rzeczy też podchodzimy tak samo? Jeśli w kodzie jest startTransaction(); commit() i rollback()

    • @adambanaszkiewicz
      @adambanaszkiewicz  2 месяца назад +1

      Transakcje są częścią warstwy Aplikacji (jestem swoją drogą w trakcie pisania tego odcinka :D ). Ta warstwa raczej średnio nadaje się do testowania jednostkowego - bardziej Funkcjonalnie lub nawet Integracyjnie z racji jej przeznaczenia. Testy jednostkowe nie powinny dotykać kodu, który dotyka infrastruktury, a transakcje są właśnie częścią infrastruktury, ale używane są w warstwie Aplikacji bo to ona odpowiada za orkiestrację całego procesu biznesowego i decydowanie co zrobić gdy coś wewnątrz transakcji zawiedzie.
      Na pewno będę o tym temacie mówił obszernie w odcinku o warstwie Aplikacji. Poproszę o troszkę cierpliwości, i jeśli po obejrzeniu odcinka nadal będziesz miał pytania to w tedy wal śmiało :) Nie chciałbym zwyczajnie pisać tutaj litanii tekstu, skoro o wiele łatwiej i przyjemniej będzie zapoznać się z materiałem video :)

    • @mleczakm
      @mleczakm 2 месяца назад

      Problemem jest "dodatkowo w serwisach jawnie korzystamy z transakcji". Wycieka wam infra.

    • @adambanaszkiewicz
      @adambanaszkiewicz  2 месяца назад

      @@mleczakm Warstwa aplikacji wie o infrastrukturę. A jeśli potrzebujesz się jej jakkolwiek pozbyć, to możesz spróbować zrobić abstrakcje na transakcję bazodanowa. W jednej z aplikacji tak zrobiliśmy, nazywaliśmy to Operacją Atomową. Pod spodem była zwykła transakcja.

  • @kosaa03
    @kosaa03 5 месяцев назад

    A jak wygląda testowanie połączenia "klasa - klasa"? Integracyjnie bez mocków?

    • @adambanaszkiewicz
      @adambanaszkiewicz  5 месяцев назад

      Tylko co chcesz tak przetestować? Powinniśmy testować zachowanie. Jeśli częścią zachowania jest odpytanie innej klasy to ta "inna" klasa powinna być używana bezpośrednio jako zależność, nie jako Mock/Spy/Fake. Jeśli podrzucisz więcej info to będę mógł odpowiedzieć bardziej konkretnie :)

    • @kosaa03
      @kosaa03 5 месяцев назад

      ​@@adambanaszkiewicz Niech będzie, że jest zachowanie "wygenerujToken", który korzysta z trzech innych klas.
      Nie dotykają żadnego API, żadnej bazy danych, nic z zewnątrz. W sumie załóżmy, że tylko do frameworka Symfony mają zależności. W takiej sytuacji najlepszym pomysłem integracyjnie to przetestować i bez żadnych mocków i dublerów?
      Czy gdyby nie było zależności do frameworka to wtedy można by jednostkowo to przetestować budując graf obiektów i też bez korzystania z mocków?

    • @adambanaszkiewicz
      @adambanaszkiewicz  5 месяцев назад +1

      Test integracyjny to test który wychodzi poza proces, czyli idzie do bazy, do systemu plików, do jakiegoś API zewnętrznego. Jeśli Twoja klasa używa Symfony, ale te klasy SYmfony nie wychodzą "na zewnątrz" to nadal to jest test jednostkowy :)
      A odpowiadając na Twoje pytanie, "wygenerujToken" jest Twoim zachowaniem, zakładam, że zwraca ten token i jego testujesz. W tedy w teście jednostkowym musisz stworzyć obiekt klasy, którą testujesz, plus wszystkie zależności tej klasy, niezbędne do wykonania tego zachowania (zakładając, że to nie jest test integracyjny jak opisałem wyżej). Nawet mając zależność do frameworka, powinieneś zbudować pełny graf obiektów, zależności, który jest potrzebny by wygenerować ten token. Oczywiście nadal mając na uwadze, że te zależności operują nadal w tym procesie, i nie "wychodzą na zewnątrz", jak opisałem w pierwszym akapicie.
      Mam nadzieję, że w miarę jasno opisałem, ale jak masz jeszcze pytania to wal, chętne podyskutuję :)

    • @kosaa03
      @kosaa03 4 месяца назад

      @@adambanaszkiewicz Czy test jednostkowy to będzie zawsze dziedziczył po TestCase? Czy po KernelTestCase też może?
      Czy w teście jednostkowym taki graf obiektów można sobie wyciągnąć z kontenera zależności czy musimy go budować ręcznie?
      W sumie zawsze rozróżniałem testy jednostkowe i integracyjne według tego czy dany test dziedziczy po TestCase (unitowy) czy KernelTestCase (integracyjny). Czy taki sposób myślenia jest poprawny?

    • @adambanaszkiewicz
      @adambanaszkiewicz  4 месяца назад +2

      Tak, taki sposób myślenia jest ok. WebTestCase/KernelTestCase uruchamia cały kernel, więc niejako od razu masz dostęp do bazy danych itp. Nie musisz oczywiście z tego korzystać, ale już sam fakt zbudowania całego kernela i kontenera DI świadczy o tym, że to test integracyjny.
      Test jednostkowy ma za zadanie przetestowanie tylko jednego zachowania, i do tego mamy TestCase.
      Co do grafu obiektów z kontenera DI - jeśli masz kontener to to nie jest test jednostkowy. Graf obiektów, które są wymagane do przetestowania danego zachowania, MUSI być stworzony ręcznie w teście. Albo przez jakiś pattern typu Fabryka lub ObjectMother, jeśli wygodniej. Natomiast samo użycie DI automatycznie przenosi test na półkę testy integracyjnego.