2012-05-31 12 views
21

Jestem tylko ciekaw, gdzie ludzie mają tendencję do używania FactoryGirl.build_stubbed i gdzie używać double pisząc specyfikacje rspec. To znaczy, czy istnieją najlepsze praktyki, takie jak "używać tylko metod FactoryGirl w swoich odpowiednich specyfikacjach modeli?"Gdzie używać `FactoryGirl.build_stubbed` i gdzie używać RSpec na` mock`/`double`

Czy to zapach kodu, gdy używasz FactoryGirl.create(:foo) w spec/models/bar_spec.rb?

Czy to mniejszy zapach kodu, jeśli używasz FactoryGirl.build_stubbed(:foo) w spec/models/bar_spec.rb?

Czy jest to zapach kodu, jeśli używasz FactoryGirl.create(:foo) w foos_controller_spec.rb?

Czy to mniejszy zapach kodu, jeśli używasz FactoryGirl.build_stubbed(:foo) w foos_controller_spec.rb?

Czy jest to zapach kodu, jeśli używasz FactoryGirl.build_stubbed(:foo) w spec/decorators/foo_decorator_spec.rb?

Przepraszamy za wiele pytań! Po prostu chciałbym wiedzieć, jak inni ludzie rysują linie w testach izolacji jednostkowej i najlepszych praktykach projektowania zorientowanego obiektowo.

Dzięki!

+0

Osobiście nawet nie wiedziałem o 'FactoryGirl.build_stubbed'. Prawdopodobnie wyjaśnia to brak odpowiedzi. Ta lub wysoka subiektywność terminu "zapach kodu". –

Odpowiedz

17

Sądzę, że istnieją najlepsze praktyki, które pomagają nam myśleć o tym, kiedy używać makiet (w tym przypadku "podwójnych") w porównaniu z rzeczywistymi zależnościami (w tym przypadku "Fabryki"). Jest naprawdę dobra książka na temat testowania (uwaga: używa przykładów Java), która opisuje cel rozwoju sterowanego testami i myślę, że jest bardzo pomocna w tej dyskusji na temat testowania aplikacji Railsowych. Opisuje on zamiar testowania następująco:

... naszą intencją w Test-Driven Development jest użycie makiety obiektów, aby wydobyć relacje między obiektami.

Freeman, Steve; Pryce, Nat (2009-10-12). Rosnące oprogramowanie obiektowe, sterowane testami (Kindle Locations 3878-3879). Pearson Education (USA). Wersja Kindle.

Jeśli myślimy o tym nacisk na wykorzystanie Test-Driven Development nie tylko uniemożliwiają nam wprowadzających regresji, ale pomóc nam myśleć o tym, jak nasz kod jest skonstruowany pod względem jego interfejs i relacji do innych obiektów będziemy w naturalny sposób stosuj makiety w wielu przypadkach. Opiszę, w jaki sposób ma to zastosowanie do poniższych pytań.

Po pierwsze, jeśli chodzi o użycie próbnych obiektów lub rzeczywistych zależności w testach modelu - jeśli testujemy klasę Foo i jej zależność od paska, możemy chcieć zastąpić próbę dla paska. W ten sposób wyraźnie zobaczymy poziom sprzężenia z Barem, ponieważ będziemy musieli kpić z metod, które będą na niego nazywane. Jeśli okaże się, że nasz model Bar jest złożony, jest to znak, że być może powinniśmy refaktoryzować Foo i Bar, aby były mniej połączone ze sobą.

W tym sensie, że zarówno Factory.create, jak i Factory.build_stubbed mają taki sam efekt, jak powstrzymywanie się od uzależniania zależności od powiązanych klas, uważam, że oba są równie śmierdzące, a Factory.create jest wolniejszym z dwóch opcji.

W moich testach staram się nie martwić zbytnio o kpiny z zewnętrznych zależności w kontrolerach.Wiem, że jest to wolniej uruchamiane niż w pełni szydercze, i nie masz korzyści z bezpośredniego powiązania kontrolera z modelem, ale szybciej jest napisać test, a ja na ogół nie martwię się o wyjaśnienie relacje między kontrolerami a utrwalonymi rekordami, którymi zarządzają. Tak długo, jak będziesz podążał za wzorami "chudych kontrolerów", nie powinno być zbyt logicznie, aby i tak się martwić. Jeśli potrzebujemy określić poziom "zapachu testowego", to powiedziałbym, że jest trochę mniej śmierdzący niż testy modelu, które zależą od innych fabryk.

Najmniej obawiałabym się najmniej o dekoratorów, którzy polegają na fabrykach klas, które dekorują. Dzieje się tak dlatego, że z definicji dekorator powinien utrzymywać ten sam interfejs co dekorowana przez siebie klasa. Dekoracja jest najczęściej realizowana z pewną formą dziedziczenia, czy to poprzez użycie method_missing do delegowania do dekoranta, czy poprzez wyraźną podklasę dekoranta. Z tego powodu łamiesz inne zasady dobrego programowania obiektowego, takie jak podstawianie Liskov, jeśli dekorator odbiega zbytnio od interfejsu rzeczy, którą dekoruje. Tak długo jak twoja dekoracja nie jest źle realizowana przez łamanie zasad dobrego dziedzictwa, sprzężenie z klasą, którą dekorujesz jest już obecne, więc to nie czyni o wiele gorszymi, jeśli masz test dekoratorów zależy od upartego lub zgaszonego fabryka rzeczy, którą zdobi. Możesz oszaleć z fabrykami w testach dekoratorów i nie ma znaczenia IMO.

Myślę, że ważne jest, aby pamiętać, że nawet jeśli wolisz mocks w większości przypadków, powinieneś nadal mieć kilka testów integracyjnych, które używają rzeczywistych zależności. Przekonasz się, że obejmują one konkretne przypadki o wysokiej wartości, w których izolowane testy jednostkowe zapewniają większy zakres funkcji zapewnianych przez Twoje zajęcia.

W każdym razie łamie wszystkie powyższe zasady czasami i są to tylko niektóre wytyczne, których używam podczas pisania testów. Nie mogę się doczekać, aby usłyszeć, jak inni używają fabryk (buildstubbed i naprawdę utrzymywanych) w porównaniu z próbnymi obiektami (double) w swoich testach.

+1

Niesamowite rzeczy! Naprawdę to doceniam. O testach integracyjnych w Railsach - na jakim poziomie testujesz, czy różne obiekty faktycznie używają właściwych interfejsów innych obiektów? Przykłady, które zawsze widzę, to testy na poziomie przeglądarki (kapibara, selen itp.). Czy istnieje dobry sposób na bardziej szczegółowe testy integracyjne (między modelami)? A może powinno to być nawet konieczne? –

Powiązane problemy