Edit: Właśnie ponownie przeczytać pytanie i zrozumiał, że nie dość odpowiedzieć. Pozostawiając moją oryginalną odpowiedź, ponieważ jest ona powiązana, ale tutaj jest twoja konkretna odpowiedź:
Powodem, dla którego nie potrzebujesz podwójnego, jest upieranie metod klasowych, a nie metod instancji. double
jest użyteczny tylko w przypadku wystąpienia instancji klasy, a nie samej klasy.
Old odpowiedź, która wyjaśnia niektóre dwukrotnie więcej:
Należy zawsze kiedy można używać prawdziwych klas zamiast podwójnej testowych. Spowoduje to zwiększenie liczby kodu i sprawi, że testy staną się bardziej kompleksowe. Podwójne testy są używane w sytuacjach, gdy nie możesz lub nie powinieneś używać prawdziwego obiektu. Na przykład, jeśli nie można utworzyć instancji klasy bez trafienia w zasób zewnętrzny (np. Sieć lub bazę danych) lub ma dużą liczbę zależności, a testujesz coś, co go używa, możesz utworzyć podwójne i odgadnij niektóre metody na podwójnym.
Oto bardziej szczegółowy przykład: powiedzmy, że testują MyClass
, ale w celu utworzenia wystąpienia MyClass
, trzeba przejść w FooLogger
:
mylogger = FooLogger.new
myclass = MyClass.new logger: mylogger
Jeśli FooLogger.new
otwiera gniazdo syslog i zaczyna spamowanie to dobrze za każdym razem, gdy przeprowadzisz testy, będziesz się logował. Jeśli nie chcesz spamować dzienników podczas tego testu, można zamiast tworzyć dublet dla FooLogger
i skrótową się metodę na nim:
mylogger = double(FooLogger)
mylogger.stub(:log)
myclass = MyClass.new logger: mylogger
Ponieważ większość dobrze zaprojektowane klasy mogą być instancja bez ubocznych efekty, zazwyczaj można użyć zamiast tego zwykłego obiektu zamiast podwójnego, a zamiast tego stosować metody pośrednie. Istnieją inne scenariusze, w których klasy mają wiele zależności, które sprawiają, że są trudne do utworzenia, a duble są sposobem na pokonanie cruftu i przetestowanie rzeczy, na której naprawdę zależy.
Z mojego doświadczenia wynika, że potrzeba użycia podwójnego to zapach kodu, ale często musimy używać klas, których nie możemy łatwo zmienić (np. Z klejnotu), więc jest to narzędzie, którego możesz potrzebować od czasu do czasu .
Rzeczywiście, jeśli spojrzeć na moim przykładzie, pierwsze Spec stubs metody instancji ** ** a drugi stubs ** metody klasy **. Wygląda na to, że obie działają dobrze, bez wcześniej używanego "podwójnego". Dlatego zastanawiam się, co daje mi dodatkowa magia "double". – grafthez
Spójrz na ten przykład Stworzyłem https://gist.github.com/anonymous/5101448. Jeśli chcę przetestować 'SchedulerJob', potrzebuję stub' RequestSchedule' i fałszywe 'RequestToQueuePusher' w prawo? Również przeszkadza mi to, że 'SchedulerJob' jest ściśle sprzężony z dwiema pozostałymi klasami. Ponieważ pochodzę ze świata Java, normalnie wyodrębniam je jako zależności, ponieważ nie ma łatwego sposobu na fałszowanie obiektów, które są tworzone na sztywno. W Ruby nie wydaje się to problemem. Widzę wiele obiektów takich jak moje 'SchedulerJob'. Wiem, że istnieje sposób na łatwe ich sfałszowanie, ale dla mnie jest to niezgodne z niektórymi zasadami SOLID – grafthez
To także kiepski projekt w świecie Ruby. Powinien istnieć sposób wstrzyknięcia zależności RequestSchedule, aby ułatwić testowanie. Możesz zrobić coś takiego: 'fakeschedule = double (RequestSchedule); RequestSchedule.stub (: new) .and_return (fakeschedule); '. To z pewnością powinno być refaktoryzowane. –