DevTalk#12 – O mockach z Pawłem Klimczykiem

27

pawel-klimczykW dwunastym już odcinku (czas leci!) mam przyjemność ponownie podywagować na temat bardzo mi bliski: testy. A konkretnie: testowanie w kontekście wykorzystania “isolating frameworks”, czyli po ludzku: mocków. Partnerem w rozmowie jest Paweł Klimczyk – programista, prelegent i “szef dotnetów na fejsie” :), czyli grup .NET Developers Poland oraz .NET Developers Poland Job Market. Na Twitterze: @pwlklm.

Podczas audycji możecie posłuchać o tym co to są mocki i na jakie grupy się je dzieli (i czy ma to sens). Jakie frameworki w świecie .NET pozwalają na wykorzystanie mocków (i jak je można skategoryzować). Do tego wpada kilka pobocznych wątków, jak na przykład: jak testować metody prywatne?

Konkurs: w tym odcinku mam dla Was egzemplarz książki “The Art of Unit Testing” Roya Osherove. Jak zwykle (ale monotonnie, co? ;) ) powędruje on do jednej z osób, które wezmą udział w dyskusji która powinna wywiązać się pod tym postem. Piszcie zarówno na temat merytoryki odcinka, jak też ogólnie o DevTalku.


Montaż odcinka: Krzysztof Śmigiel.
Ważne adresy:

Linki


Muzyka wykorzystana w intro:
“Misuse” Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 3.0
http://creativecommons.org/licenses/by/3.0/
Share.

About Author

Programista, trener, prelegent, pasjonat, blogger. Autor podcasta programistycznego: DevTalk.pl. Jeden z liderów Białostockiej Grupy .NET i współorganizator konferencji Programistok. Od 2008 Microsoft MVP w kategorii .NET. Więcej informacji znajdziesz na stronie O autorze. Napisz do mnie ze strony Kontakt. Dodatkowo: Twitter, Facebook, YouTube.

27 Comments

  1. Do mockowania System.DateTime.Now używam takiego rozwiązania:
    public static class SystemTime
    {
    public static Func Now = () => DateTime.Now;
    }

    Użycie:
    DateTime now = SystemTime.Now();

    A w testach:
    [SetUp]
    public void Initialize()
    {
    SystemTime.Now = () => new DateTime(2018, 01, 01);
    }

  2. Apropo auto-mocking containers, to od jakiś dwóch miesięcy używam AutoFixture (https://github.com/AutoFixture/AutoFixture) i przyznam szczerze że świetna sprawa. O ile w nowych aplikacjach (aplikacjach pisanych od zera czy no nazwijmy je bardziej na czasie) duża ilośc zależności klasy rzeczywiście świadczy o bad design,o tyle przy aplikacjach ponad 10-letnich i tzw. legacy code, gdzie klasa przyjmuje 5 zależności i lepiej nie wyobrażam sobie mockowania wszystkich zależności. Zwłaszcza gdy potrzeba przetestować (co głownie jest ideą testowania) jakiś kawałek, w którym user znalazł błąd, a refactoring nie wchodzi w rachubę ;) Używając automocking containers tworzysz sobie sut’a, mockujesz co potrza i jazda.

    Odnośnie dzisiejszego odcinka: poziom dobry, rozmowa na temat. Okazało sie że całe życie używałem constrained framework mocks, a tu jest jeszcze nowy level do wbicia w postaci uncinstrainded mocking frameworks ;)

  3. Grzegorz on

    Hej!
    Bartdzo ciekawa seria podcastow – dzis przesluchalem 75% z calej serii.
    Co do mockowania – zawsze mnie intruguje jak dobrze mockowac ef – bo setup czasami zajmuje caly ekran, a mnie uczono, ze jak cos jest na caly ekran – to znaczy ze jest za duze (a wtedy nie bylo rozdzielczosci fullHD).

    Mysle, ze przeslucham podcast dwa, trzy razy i wroce z pytaniami, bo musze zaladowac nowe namesaces do osrodka decyzyjnego…
    G

  4. Ireneusz Patalas on

    @Grzegorz: co do Entity Frameworka to niedawno znalazłem coś takiego jak Effort: http://effort.codeplex.com/ Wygląda całkiem zacnie, ale przyznam, że jeszcze nie sprawdzałęm, bo teraz jestem w innym projekcie i EF nie mamy.

    Co do fake’owania DateTime.Now to jest jeszcze jeden fajny sposób, który mi się bardzo podoba, bo nie wymaga żadnych zmian w kodzie (no prawie… ale o tym zaraz). Fody.Ionad (https://github.com/Fody/Ionad). Dla tych co nie znają Fody to w dużym uproszczeniu można za jego pomocą (a dokładniej jego pluginów) dokonywać “post-processingu” kodu tuż przed jego kompilacją. Nie ma to wpływu na oryginalne pliki z kodem, ponieważ dzieje się to w locie.
    Fody.Ionad daje możliwośc podmiany dowolnego statycznego odwołania na inne. Przykład z DateTime.Now jest akurat na stronie, więc nie będę go bezsensownie przeklejał. Jest to o tyle fajne, że możemy to zrobić praktycznie w dowolnym momencie istnienia projektu nawet mając już bardzo dużo odwołań do DateTime.Now. Nie trzeba wprowadzać produkcyjnie tej “furtki dla testów” oraz nie trzeba w ogóle modyfikować kodu. Zmodyfikuje się on oczywiście w locie przed buildem, ale oryginalny kod nie zostanie zmieniony i w kontroli wersji cały czas mamy stary dobry DateTime.Now.
    Jak ktoś zapomniał o wprowadzeniu warstwy abstrakcji dla czasu (IMHO to już zakrawa lekko na paranoję, bo ta warstwa izolacji pełni tylko rolę furtki dla testów, nie ma sensu wstrzykiwać tutaj np. za pomocą DI innej funkcjonalności) to może to być ciekawa alternatywa dla TypeMock/Microsoft Fakes, które dla mnie są raczej niewymagającym refleksji workaround’em. Dodatkowym atutem będzie fakt, że jeśli przy projekcie pracuje więcej osób to nie muszą one uczyć się nowego dostępu do czasu (przez jakieś własne SystemTime.Now czy podobne), a co za tym idzie nie ma ryzyka przegapienia kilku wystąpień.

    @procent: to już któryś raz jak widzę, że używasz terminu Microsoft Moles. Ten twór MS’a przekształcił się w Microsoft Fakes w okolicach 2012 roku i jako Moles nie jest już rozwijany. MS Fakes natomiast jest już integralną częścią VS (na pewno 2013, nie wiem czy 2012 też). Z własnych doświadczeń nie polecam go jednak… pomijając kwestie ideologiczne wspomniane wyżej, mieliśmy z nim różne dziwne problemy. Niektóre objawiały się dopiero na build serwerze a lokalnie działały. Bywają problemy z odświeżaniem wygenerowanych bibliotek z fake’ami (np. zmieniła się wersja), poza tym zajmuje to dużo miejsca. Tak, wiem, miejsce teraz jest tanie, ale nie lubie patrzeć jak projekt zajmuje przykładowo 1GB, a z tego 800MB to wygenerowane fake’i przy różnych projektach w solucji. Można to mocno poprawić generując fake’i tylko dla wybranych typów, ale to niewygodne i powoduje kolejne problemy przy odświeżaniu. Jestem przeciwnikiem używania tego typu narzędzi, ale muszę przyznać, że jest to często dużo szybsze rozwiązanie niż refactor architektury, która nie zawsze jest idealna.

  5. @Piotrek,
    Ano tak, AutoFixture jest całkiem przyjemne o ile się go nie nadużywa. Dopóki robi co ma robić a ja nie piszę autofac-specific-code to jest spoko, w przeciwnym wypadku AutoFixture wędruje za okno (tak jak Automapper).
    Temat automocking containers poruszyłem podczsas rozmowy żeby raczej “odchęcić” od ich stosowania.

  6. Grzegorz,
    No to gites, chwała i cześć i tak dalej :).
    EF nie używam, ale bym nie mockował (tak jak nie mockuję NH). Kontakt z bazą danych powinien raczej siedzieć w komponentach które nie zawierają za bardzo logiki biznesowej – same klasy “logiczne” przyjmują dane jako parametry i wtedy te dane po prostu tworzysz w teście i przekazujesz. Jeśli mówimy o testach integracyjnych to stawiasz bazkę dla każdego testu i tyle. Ale tych testów w założeniu nie powinno być dużo, bo i za bardzo nie powinno być czego testować (poprawność zapytań linq?).

  7. @Ireneusz Patalas,
    Fody to “code weaving” – coś wg mnie jeszcze gorszego niż wpinanie się do projektu przez profiler API jak to robi Isolator :).
    A tworzenie warstwy abstrakcji nad czasem nie jest tylko furtką dla testów jednostkowych – niedawno pisałem małą aplikację konsolową która zarządza procesem fakturowania, wysyłania płatników do windykacji itd. Proceserm tym rządzą oczywiście ściśle określone reguły mające w sobie dużo odniesień do czasu właśnie (wystaw fakturę, po 2 tygodniach wyślij przypomnienie, po kolejnych 2 drugie przypomnienie, potem -> windykacja). Klient mówi “chciałbym zobaczyć jak to działa”… i co ja mam mu powiedzieć: przetestuj dopiero w produkcji albo przestawiaj czas w windowsie? To by było średnio “pro” :). A tak – dodaliśmy parametr “-now” do linii komend, wartość tego parametru wstawiana jest właśnie jako to moje SystemTime. I śmiga.

    Dzięki za info o Moles/Fakes. Nie interesuję się tym zupełnie bo również jestem przeciwnikiem takich narzędzi, stąd moje niedouczenie :).

  8. @Maciek
    Co rozumiesz pod pojęciem “… nadużywanie automocking containers…”? W tej chwili widzę więcej zalet stosowania ich niż wad, no ale może są jakieś wypowiedzi mądrych głów, które chętnie przeczytam, żeby zgłębić temat… bo może się okazać że mam oczy szeroko zamknięte w temacie ;)

  9. Piotrek,
    Automocking containers z mojej perspektywy:
    1) ukrywają problem wielu zależności – jeśli mam klasę z 6 czy 10 parametrami, to jej przetestowanie POWINNO BYĆ TRUDNE, powinienem czuć dyskomfort ręcznie tworząc te 6 czy 10 mocków po to, żeby ten kod zrefactorować; automocking container to po prostu ukryje przede mną, a burdel zostanie
    2) automocking container tworzy jakieś tam swoje instancje i żeby potem przetestować interackję SUT z zależnościami muszę ponownie robić resolve() na kontenerze w moich testach – samo założenie mi się nie podoba

  10. Ireneusz Patalas on

    @procent: Zgadza się, że code weaving to nie jest dobra metodologia do pisania aplikacji, ale… to jest tylko narzędzie i podobnie jak nóż może zostać użyte dobrze lub źle :)
    Ja Fody znam głównie z pluginu do INotifyPropertyChanged, o którym wspominaliście z Basią przy okazji AOP i tam nadaje się to wg mnie świetnie. Oczywiście zaciemnia częściowo kod, bo to dzieje się jakby poza kontrolą, ale w tym przypadku chyba jednak wole nauczyć wszystkich jak to działa niż mieć klasy modelów z ręcznie zaimplementowanym tym interfejsem dla każdego propsa rozdmuchane na 3 kilometry.
    W przypadku DateTime.Now jestem nawet w stanie wybaczyć użycie Isolatora czy MS Fakes, mimo tego że za nimi nie przepadam. Gorzej kiedy ktoś zaczyna tym mockować własny kod (no nie zawsze dosłownie własny, ale kod projektu, a nie .NET’a). Wtedy to sygnał, że architektura kuleje i przydałby się refactor. Tutaj niestety jeszcze do głosu często dochodzi biznes, który może dać veto dla większego refactora z różnych powodów. Świat nie zawsze jest taki czarno-biały i nawet jak dev chce dobrze to może nie mieć takiej możliwości.

  11. Hej! Testy to temat mi również bardzo bliski.

    Co do różnic pomiędzy stub-ami i mock-ami to trochę zagmatwaliście :). Jest jedna, logiczna. Fizycznie niczym się od siebie nie różnią. Na stub-ach nie robimy asercji/weryfikacji. Robimy to na mockach. Stuby zapewniają niezbędne dane wejściowe, mocki pozwalają weryfikować poprawność działania kodu. Częstym błędem jest robienie asercji na obiektach, które powinny być traktowane jako stub-y w danym teście.

    Co do testowania metod prywatnych to ja akurat nie widzę żadnego problemu. Tego po prostu się nie robi :) Prywatne metody to szczegół implementacyjny. Testujemy interfejs publiczny klasy. To, że metoda publiczna woła 10 metod prywatnych nie ma znaczenia. One są testowane pośrednio przez test metody publicznej. Gdybyśmy testowali metody prywatne otrzymalibyśmy testy, które wywalają się przy każdym refactoringu. Ostatnio coraz częściej słyszę głosy, że Unit testy to za niski poziom i że przeszkadzają w refactoringu. Wg mnie tylko te źle napisane.

    Chyba nie zrozumiałem Waszego komentarza odnośnie tworzenia nowych klas jeżeli jest dużo metod prywatnych. Ja nie widzę niczego złego w tym. Wręcz przeciwnie! Wzorzec composed method sugeruje rozbijanie dużych metod na wiele małych co czyni kod o wiele bardziej zrozumiałym/samo dokumentującym się. Tego samego uczy Uncle Bob. Tworzenie klas tylko po to, aby powstały jakieś metody publiczne, aby można je było testować jest moim zdaniem błędem (jJuż wyżej napisałem, że bez tego można je testować pośrednio). Prowadzi do eksplozji ilości klas, które są publiczne chociaż wcale nie powinny, lub internal i zmuszanie do korzystania z InternalsVisibleTo.

  12. A jeżeli w wyniku refactoringu z metod prywatnych powstaje klasa to wcale nie trzeba jej wstrzykiwać. Co więcej, wcale nie trzeba pisać dla niej nowych testów. Te testy już istnieją! To testy klasy, która zawierała te prywatne metody wyniesione do nowej klasy. Pisał o tym kiedyś na swoim blogu Uncle Bob.

  13. Piotr Perak,
    Jeśli trzeba wykonać asercję na obiekcie będącym stubem to oznacza to że to nie jest stub :) dlatego dla mnie wszystko jest mockiem i tyle, o to mi chodziło,

    Testowanie metod prywatnych – tak jest, nie robi się. Jeśli taka metoda jest na tyle skomplikowana że wymaga przetestowania osobno, to tak jak mówiliśmy wyciąga się ją do innej klasy. Nie jest to po to żeby cos było publiczne tylko dla testów, tylko po to żeby zachować SRP. Jeżeli metoda woła 10 metod pomocniczych to raczej wszystko to nie dotyka tylko jednego aspektu systemu i można z tego zrobić kolejne odrębne komponenty.

  14. Czy wszystko nazywamy mockami, czy część stubami, a część mockami nie ma takiego znaczenia. Ważne, abyśmy wiedzieli na czym nie powinniśmy robić asercji.

    Co do SRP to nie musimy o tym pisać. Jasne, że zgodność z nią najpierw.

    Jakoś nie czuję tego ze złożonością metody prywatnych. Z definicji wykonują one część pracy metod publicznych. Jeżeli złożoność metody publicznej to jej kod + kod wywoływanych metod prywatnych to siłą rzeczy metody publiczne są bardziej skomplikowane niż metody prywatne. I każda ścieżka w metodzie prywatnej jest osiągalna przez interfejs publiczny klasy. Jeżeli nie, to można taką ścieżkę usunąć, bo jest nieużywana.

    U mnie metody prywatne to często 1-3 linijki powtarzającego się w klasie kodu. Nie zdarzyło mi się, aby jakoś utrudniały mi testowanie.

  15. Grzegorz on

    No no ładnie się tu porobiło :-)
    @Ireneusz Patalas – dzięki za wskazówkę – bedę to maglował z szefem – szczególnie ze zapytania testuje w LinqPad’dzie i nie widze tutaj wiekszego sensu na inne testy.
    @Maciej Aniserowicz – fajni by bylo uslyszec cos na temat testo UI – ja osobiscie zrobiłem piersze kroki w Selenium z driverem pod IE i firefoxa oraz w zeszlym roku zautomatyzwoalem testy UI dla aplikacji formatkowej uzywając SIKULI (no i się trochę pytona poduczyłem)
    Testy UI są dla mnie o tyle ciekawe, gdyz dziś UI tak napradę decyduje o sprzedazy aplikacji i odbiorze przez klienta, a od kilku miesięcy siedzę w projecie webowym i mamy tu wiele kwatków które trzeba pięlędnowac i podlewać testami (smingus dingus idzie)

    pozdrowienia!

  16. Grzegorz on

    i przepraszam za pozjadane znaki…. byłem przed przerwą śniadaniową :P

  17. @Grzegorz

    Jeżeli chodzi o mockowanie EF to jest to bardzo proste. Tworzysz interfejs np. IMojDbContext, który jako właściwości ma IDbSet. W testach korzystasz z InMemoryDbSet i ot cała filozofia. Tylko bądź świadom jednej rzeczy. Teraz zapytania to LinqToObjects, a więc przejdzie wszystko. Te same zapytania odpalone na bazie danych mogą być nie wspierane. Więc to kwestia dyskusyjna, czy te testy coś dają.

  18. Grzesiek Gałęzowski on

    Dzięki za dev talka!

    Zanim skomentuję (i ktoś odbierze mnie jako agresora który się czepia :-)), chciałem napisać, że fajnie się słuchało, miło było poznać Wasze doświadczenia i że ten dev talk był dla mnie pożyteczny. A teraz komentarz :-)

    Osobiście szkoda mi trochę, że mówiąc o mockach skupiliście się na temacie Constrained/Unconstrained (może tytuł powinien być troszkę inny?), a pominęliście podstawowe źródło wiadomości na ten temat, czyli Growing Object Oriented Software Guided By Tests. Niestety, jakoś w .NETowym środowisku ignorowanie tej książki i tego co w niej jest napisane jest zjawiskiem powszechnym. Chyba nawet sam Roy Osherove przeczytał ją dopiero po tym jak wymyślił swoją terminologię “isolating frameworks” (IMO zupełnie rozmijającą się z tym, po co mocki były pomyślane). Mocki były też dziwnie rozumiane w innych pozycjach o sporym autorytecie, np. Meszaros w swoim XUnit Test Patterns zawarł je w sekcji “Back Door Manipulation” (!!!).

    Szkoda, bo fajnie by było przybliżyć słuchaczom podejście tam zawarte. Z ignorowania tej książki i tego co jest w niej napisane (autorzy zanim wprowadzają mocki, przez prawie kilkadziesiąt stron wyjaśniają swój “opinionated view” – poglądy na projektowanie obiektowe i jak mocki tam pasują) moim zdaniem wzięła się większość tzw. “argumentów przeciw mockom”, jak np. ten, że mocki psują enkapsulację, a także ten, że lepiej jest używać mocków poza modelem domeny itp. (w sumie to nie mówicie o tym, ale jakieś tam echa pod koniec dyskusji pobrzmiewają).

    Jak napisał kiedyś Steve Freeman, jeden z autorów: “mocks arise naturally from doing responsibility-driven OO. All these mock/not-mock arguments are completely missing the point. If you’re not writing that kind of code, people, please don’t give me a hard time.” (https://groups.google.com/forum/#!msg/growing-object-oriented-software/rwxCURI_3kM/2UcNAlF_Jh4J)

    Nat Pryce, drugi z z autorów, również bardzo mocno uzależnia “stosowalność” mocków od przyjętego stylu projektowania: “when focusing the design (and therefore tests) on messaging protocols, I do not specify anything about the state of an object. I only test in terms of incoming and outgoing messages to/from the object under test. State and mutation is implied by the test when the object’s response to later messages is affected by earlier messages it has received. But I don’t specify what that state is and how it is represented. It’s an internal implementation detail.

    That’s why I argue that there are not different kinds of TDD. There are different design conventions, and you pick the testing techniques and tools most appropriate for the conventions you’re working in. And different parts of the system will probably use different conventions.” (https://groups.google.com/forum/#!topic/clean-code-discussion/A6sJQjnwvnA).

    Jakiś czas temu zacząłem pisać książkę na leanpubie o TDD (nie podam linka, żeby nie było że autopromocja ;-)) i przyjąłem sobie za punkt honoru, że wyjaśnię przystępnie podejście do obiektowości które sprawia, że mocki są użyteczne. Z krótkiego wstępu zrobiło się ponad 100 stron, bo temató jest sporo: interfejsy, protokoły, klasy, kompozycyjność, kompozycjonalność, refaktoryzacja kompozycji obiektów do języków specyficznych dla domeny, obiekty wartości (Value Objects) itp.

    Btw, jeśli chodzi o date/time – ja przekazuję “bardziej domenowe” opakowanie do wszystkich obiektów które tego potrzebują. Jeśli rzeczywiście jest tak, wiele miejsc potrzebuje daty i czasu, to coś w mojej architekturze prawdopodobnie jest nie tak – staram się, by data/czas były używane przez malutką liczbę obiektów, które następnie są przekazywane dalej jako potężniejsze abstrakcje. Wolę, żeby jak najwięcej obiektów zależało od tych potężniejszych abstrakcji, bo pomaga mi to optymalizować design pod kątem zastępowalności (jeśli mam interfejs np. IDevTalkTime – jak dużo sensownych różnych implementacji takiego interfejsu mógłbym wymyśleć? Dwie? Trzy? Dlatego jak dla mnie jest to dosyć słaba abstrakcja i wolę ją ukrywać jak się da).

    Książka Osherove’a (mam na myśli wydanie pierwsze – drugie podobno jest sporo zmienione) jest książką dla początkujących i nawet sam autor przyznał, że wizja projektowania obiektowego tam zawarta była naiwna (nie mam pod ręką źródła, ale to była jakaś prelekcja), dlatego warto by polecić czytelnikom słuchaczom jakieś bardziej zaawansowane pozycje.

    Pozdrawiam serdecznie i dzięki jeszcze raz za DevTalka!

  19. Grzesiek Gałęzowski on

    Eh, wygląda na to, że zjadło mi wszystkie biało znaki :-(. Przepraszam za tę “zupę” powyżej…

  20. Dzięki za dyskusję,
    Książka powędruje do Piotr Perak, a Grzesiek Gałęzowski będzie mógł pić kawę z DevTalkowego kubeczka :). Poszły maile z prośbą o adres.

  21. @Maciej Aniserowicz
    Co myślisz o urozmaiceniu dev talków o video w którym byłoby widać prowadzącego i gościa. Oczywiście osobno, wystarczyłoby włączyć kamerke podczas rozmów.

  22. Qba,
    Zastanawiałem się nad tym i definitywnie tę opcję odrzuciłem. Podcast to podcast, gadające głowy można sobie puścić w tle w TVN24 :)

  23. @Piotr Perak:
    Odnosnie roznic stub/mock – dobrze piszesz. Ja chcialem rozwinac troche wypowiedz i pokazac wiekszy kontekst. W programowaniu przewaznie uzywam mockow.
    Metody prywatne wymagajace testowania – kurde, zrobilm bym z tego klase osobna, bo widocznie to co jest w srodku robi sporo i powinnno byc wyabstrahowane.

    @Grzegorz:
    UI Testing – temat na osobny podcast :) W tym podkascie chodzilo o pokazanie samej idei mockow.

    @Grzesiek Gałęzowski:
    Growing Object Oriented Software Guided By Tests – to juz temat TDD.
    Ksiazke przeczytam :). Nawiazajac do Twojego podejscia do mockowania DateTime i wprowadzania abstrakcji to jest ono dobre, gdy buduje sie system. Problem pojawia sie gdy lądujesz w projekcie, gdzie kod ma juz kilka lat i dodajesz nowe funkcje. Wtedy trudno abstrahowac DateTime i (może) łatwiej mockować to co jest.

    Ciesze sie, że wywiązała się tutaj taka dyskusja.

  24. Grzesiek Gałęzowski on

    @Paweł Klimczyk GOOS to temat TDD, ale bardzo mocno mocków właśnie (choć nie tylko). Z wstępu do książki: “Our original motivation for writing the book was to finally explain the technique of using mock objects, which we often see misunderstood.”. Chociaż owszem, mocków można używać inaczej trochę niż jest opisane w tej książce, np. do starego kodu. Tylko wtedy nie są to takie mocki w sensie stricte, gdyż oryginalne mocki rzucały wyjątki gdy otrzymały niespodziewane wywołania (w świecie C# i Javy uważa się obecnie to podejście za przestarzałe i prowadzące do kruchych testów, natomiast JMock – biblioteka autorów GOOS – wciąż opiera się na takich właśnie mockach i autorzy twardo stoją przy stanowisku, że w takim sposobie wykorzystania mocków jaki oni preferują jest to lepsze podejście, dlatego że dla nich naturalnym podejściem do projektowania jest projektowanie “protokołocentryczne”).

    Z tym Date Time w starym kodzie to zgoda, natomiast pole manewru zależy od narzędzi. Jeśli ma się dobre automatyczne narzędzie do refaktoryzacji, to najczęściej nie trzeba mockować tego co jest – w r# często sprawę załatwia kombinacja “Extract Method-> Extract Class->Introduce Parameter (jako parametr konstruktora)->Extract Interface->Use Base Type Where Possible”, którą można zrobić niemal mechanicznie.