2009-03-27 13 views
11

W .net, inaczej niż w Javie, metody nie są domyślnie wirtualne. Aby korzystać z większości pozornych struktur obiektów, musisz albo oznaczyć metody, których chcesz użyć w swoim symulatorze jako wirtualne na "prawdziwym" obiekcie, albo musisz mieć interfejs, który możesz udawać, że testowana klasa będzie zaakceptować zamiast wdrożenia.Szydercze obiekty - zadeklaruj wszystkie metody jako wirtualne lub użyj interfejsu?

Wygląda na to, że źle się układa i zaznacza każdą metodę jako wirtualną, ale wygląda na to, że definiuje interfejs dla każdej klasy.

Co najlepiej zrobić?

Odpowiedz

8

Moja zasada polega na zdefiniowaniu interfejsu, jeśli spodziewam się wielu implementacji - rzeczywistych konkretnych klas aplikacji lub pojedynczej implementacji aplikacji i fałszywej implementacji do testowania jednostkowego. Jeśli oczekuję tylko jednej implementacji i klasa nie potrzebuje fałszowania (większość nie), to w razie potrzeby przejdę drogą wirtualną i refaktorem do interfejsu.

+0

Podoba mi się pomysł traktowania podwójnych testów jako planowanych implementacji interfejsu. Nie jestem pewien, czy podoba mi się uczynienie innych wirtualnymi, chyba że są częścią projektu klasowego, ale potem znowu, jeśli okaże się, że trzeba wyśmiewać coś później, zmieniając kod właśnie za to śmierdzi. – dnewcome

0

Kto mówi, że fałszywy obiekt musi pochodzić z tej samej hierarchii klas?

Znacznie łatwiej jest stworzyć prostą klasę autonomiczną, która ma wymagany interfejs i tworzy wystąpienia tego obiektu.

Można nawet utworzyć hierarchię klas próbnych i użyć ich do celów testowania jednostkowego.

+0

Dzięki za odpowiedź. Rozumiem, do czego dążysz, ale aby test podrzędny działał z próbą, musi być wyprowadzony z tego samego interfejsu, który realizuje rzeczywisty obiekt lub bezpośrednio z prawdziwej klasy. Myślę, że ta próbka musi zadowolić relację "Is A". – dnewcome

+0

@dnewcome: Wygląda na to, że masz rację. To, co napisałem, byłoby dużo lepsze dla języków używających pisania na klawiaturze. –

11

Jeśli będę musiał wybrać między dwoma, pójdę z rzeczą interfejsu. Interfejs ma na celu zdefiniowanie kontraktu, który jest zasadniczo tym, do czego będzie się stosować fałszywy obiekt. Oznaczenie metody jako wirtualnej może mieć nieprzewidziane skutki uboczne. Wpływa na projekt prawdziwej klasy, która jest wyśmiewana. Interfejs jedynie definiuje nazwy metod i nie ma wpływu na prawdziwą klasę.

+2

Ma to sens z punktu widzenia poprawności. W .NET, dla mnie określenie metody wirtualnej wskazuje, że projektant klasy zamierza to gdzieś zastąpić. Nie można go również wpisać, itd., Jeśli chodzi o efekty uboczne. Masz rację co do tego, że mock przylega do kontraktu, myślę. – dnewcome

-1

Najlepiej użyć głowy. Zastanów się nad swoim scenariuszem, jeśli rozsądniej będzie użyć wirtualnego, niż to zrobić. Jeśli jednak interfejs lepiej pasuje do twojego zadania, zrób to.

Tak naprawdę to widzę jak to na dodaniu nowej funkcjonalności

  • Dziedziczenie: stosowanie metod wirtualnych.
  • Skład: Użyj interfejsów.

Jestem pewien, że istnieje szereg zastrzeżeń do tego. Więc używaj swojej głowy i rób to, co jest najłatwiejsze w twoim scenariuszu.

+1

To, co powiedziałeś, jest zdecydowanie najlepszą praktyką w projektowaniu klas. Problem w tym, że tak naprawdę nie mam na nie wezwania. Klasy, z których kpię, są generalnie niezależne w działaniu i nie potrzebuję metod wirtualnych, poza włączeniem makiet. – dnewcome

+0

Jeśli próbujesz wyśmiać coś, czego nie można wyśmiać, jest kilka opcji. Najpierw sprawdź, czy TypeMock może ci pomóc.Jeśli nie, to położyłbym na nim Fasade i zaimplementowałem interfejs. Stamtąd możesz po prostu kpić z interfejsu i żyć dalej. Keep jest prosty !! –

Powiązane problemy