Kiedy powinienem używać fałszywych obiektów?

14

Czytałem wiele rzeczy o TDD, ale wciąż mam wątpliwości. Na przykład mam te diagramy klas:

wprowadź opis zdjęcia tutaj

To prosty przykład, aby dowiedzieć się więcej o TDD i próbnych obiektach.

Który test powinienem napisać jako pierwszy? Produkt , następnie linia i ostatni, zamówić ? Jeśli to zrobię, czy powinienem używać Linii i Produktu do testowania Zamówienia, czy też powinienem używać Próbnych Obiektów? Kiedy powinienem używać Mock Objects? Czy powinienem używać UML z XP i TDD?

Nie rozumiem jeszcze tych rzeczy.

Zanon
źródło

Odpowiedzi:

10

Sądząc z diagramu, produkt jest głupią klasą danych, bez funkcji do testowania. Zacznę więc pisać testy dla (i implementacji, stylu TDD) pierwszej linii, a potem porządku, w górę drabiny zależności. Zazwyczaj rozsądne jest przetestowanie klas niższego poziomu przed rozpoczęciem pracy na klasach wyższego poziomu (tj. Zależnych od niższego poziomu). To sprawia, że ​​łapanie błędów jest bardziej wydajne.

To, czy chcesz użyć obiektów pozornych, zależy od rzeczywistych zależności testowanej klasy. Jeśli są to proste klasy, które można łatwo utworzyć i skonfigurować z dowolnymi danymi / stanami wymaganymi do testów, nie trzeba próbować. (Wydaje się, że tak jest w przypadku twojego przykładowego projektu.) Jednak jeśli którakolwiek z zależności jest trudna do zainicjowania / sama ma rozległe zależności / ma niepożądane skutki uboczne / zależy od zewnętrznego zasobu, takiego jak baza danych, to ma to sens zamiast tego użyć próbnego obiektu.

Péter Török
źródło
Jak powiedziałem wcześniej, był to prosty scenariusz, aby dowiedzieć się więcej o obiektach TDD i Mock ... Świetna odpowiedź, dziękuję. A co z UML? Czy powinienem tego unikać?
@ thomas, nie trzeba unikać UML, nie powoduje konfliktu z TDD. UML jest bardzo dobry do wizualizacji / komunikowania problemów projektowych. Może to być niezwykle przydatne na niektórych etapach rozwoju. Jednak projektowanie ewoluuje, a próba utrzymania pięknego i szczegółowego schematu systemu UML w synchronizacji z kodem może szybko stać się dużym obciążeniem. Pamiętaj więc, aby wyrzucić, gdy już go nie potrzebujesz :-)
Péter Török
1
@ thomas, przy okazji konwencja polega na głosowaniu na odpowiedzi, które uważasz za przydatne, klikając strzałkę w górę obok odpowiedzi :-)
Péter Török
4

Nie widzę tu zbytniej potrzeby na fałszywe obiekty. Jak zauważyli inni, potrzebujesz ich głównie, jeśli zależności są trudne do skonfigurowania.

Na przykład używaliśmy ich z projektami Ruby on Rails, kiedy testowaliśmy kontrolery i potrzebowaliśmy loginu użytkownika, który wymagałby połączenia z innym kontrolerem i przechowywania części jego informacji w pliku cookie. W takim przypadku pomocne jest wyśmiewanie zalogowanego użytkownika, który zwraca wartość true, gdy zostanie zapytany o określone uprawnienia dostępu.

Thorsten Müller
źródło
2

Zwykle do testowania chcesz odizolować testowany system / obiekt, aby wyśmiewać wszystko, co jest poza tym. Korzystając z diagramu klas, podczas testowania obiektu zamówienia, użyj makiety obiektu liniowego. Podczas testowania linii użyj makiety zamówienia i produktu. Podczas testowania produktu użyj makiety linii.

Czarny lód
źródło
Ponieważ Produkt nie zależy od Linii, nie ma potrzeby (ani sposobu) używania w tym miejscu makiety dla Linii. To samo dotyczy linii i zamówienia.
Péter Török
2

„TDD to przede wszystkim technika projektowania, której efektem ubocznym jest sprawdzenie, czy kod źródłowy jest dokładnie testowany jednostkowo” - Scott W. Ambler

Chodzi o to, aby znaleźć projekt, pisząc testy jednostkowe. W twoim przypadku wydaje się, że masz już gotowy projekt, który niejako podważa cel TDD (zakładając, że twój projekt jest ostateczny).

Odnośnie kpiny. Jeśli chcesz kpić, sugeruję wyśmiewać Produkt podczas pisania testów dla Linii i próbować Linii podczas testowania Zamówienia. Ale tutaj może być przesada. Osobiście staram się ograniczać kpiny tak bardzo, jak to możliwe, i używam go do rozdzielania zależności od klas zewnętrznych (takich jak instancje bazy danych).

Martin Wickman
źródło
2
Mam tylko prosty schemat klas ...
-1 Więc myślenie o projekcie (w tym zapisanie schematu klasowego) uniemożliwia ci zrobienie TDD? To brzmi po prostu źle.
Bjarke Freund-Hansen
1
@bjarkef: Przeczytaj ponownie moją odpowiedź. Jeśli projekt jest ostateczny, tak naprawdę nie można użyć TDD do wyparcia projektu, na tym właśnie polega TDD. I myślę, że to właśnie powoduje, że OP jest zdezorientowany: ma już rozwiązanie i teraz próbuje napisać dla niego testy. „Które testy powinienem najpierw napisać, produkt lub zamówienie”. To pytanie nie ma większego znaczenia, jeśli najpierw napiszesz testy.
Martin Wickman
Jak ustalić, że projekt jest ostateczny bez żadnych testów ani kodu produkcyjnego? Zakładając, że chcesz stworzyć coś, co działa.
JeffO
@Jeff: Oczywiście nie możesz. To jedna rzecz, w której TDD może ci pomóc.
Martin Wickman