Twoje pytanie dotyczyło różnic między frameworkiem MS Fakes a NMock i wydaje się, że inne odpowiedzi częściowo rozwiązały ten problem, ale tutaj jest więcej informacji na temat tego, czym są takie same i czym się różnią. NMock jest również podobny do RhinoMocks i Moq, więc grupuję je w NMock.
Istnieją 3 główne różnice, które widzę od razu między NMock / RhinoMocks / Moq i MS Fakes Framework:
Fake framework MS używa wygenerowanego kodu, podobnie jak Accessors w poprzednich wersjach programu Visual Studio zamiast typów ogólnych. Jeśli chcesz użyć fałszywej struktury dla zależności, dodaj zestaw, który zawiera zależność, do odwołań do projektu testowego, a następnie kliknij go prawym przyciskiem myszy, aby wygenerować podwojenie testu (kody pośredniczące lub podkładki). Następnie podczas testowania w rzeczywistości używasz tych wygenerowanych klas. NMock używa generycznych do osiągnięcia tego samego (tj IStudentRepository studentRepository = mocks.NewMock<IStudentRepository>()
.). Moim zdaniem podejście ramowe MS Fakes utrudnia nawigację po kodzie i refaktoryzację z poziomu testów, ponieważ w rzeczywistości pracujesz z wygenerowaną klasą, a nie z prawdziwym interfejsem.
Fałszywe ramy MS dostarczają stubów i pieprzyków (podkładek), podczas gdy NMock, RhinoMocks i Moq wszystkie zapewniają niedopałki i makiety . Naprawdę nie rozumiem decyzji stwardnienia rozsianego, aby nie uwzględniać kpiny i osobiście nie jestem fanem pieprzyków z powodów opisanych poniżej.
Dzięki frameworkowi MS fałszywych możesz zapewnić alternatywną implementację metod, które chcesz zablokować. W ramach tych alternatywnych implementacji można określić zwracane wartości i śledzić informacje o tym, jak i czy metoda została wywołana. Za pomocą NMock, RhinoMocks i Moq generujesz obiekt pozorowany, a następnie używasz tego obiektu do określenia wartości zwracanych przez skrót lub do śledzenia interakcji (czy i jak zostały wywołane metody). Uważam, że podejście do podróbek MS jest bardziej złożone i mniej wyraziste.
Aby wyjaśnić różnicę w tym, co zapewniają frameworki: NMock, RhinoMocks i Moq zapewniają dwa typy testów podwójnych (stubs i mock). Fałszywe ramy zapewniają niedopałki i pieprzyki (nazywają je podkładkami) i niestety nie zawierają prób. Aby zrozumieć różnice i podobieństwa między NMock i MS Fakes, pomocne jest zrozumienie, czym są te różne typy testów podwójnych:
Stubs: Stubs są używane, gdy musisz podać wartości metod lub właściwości, o które zostanie poproszony o podwojenie testu przez testowaną metodę. Na przykład, gdy moja testowana metoda wywołuje metodę DoesStudentExist () podwójnego testu IStudentRepository, chcę, aby zwracała wartość true.
Pomysł na stuby w podróbkach NMock i MS jest taki sam, ale z NMock można zrobić coś takiego:
Stub.On(mockStudentRepository).Method("DoesStudentExist").Will(Return.Value(true));
A z MSFakes zrobiłbyś coś takiego:
IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository() // Generated by Fakes.
{
DoesStudentExistInt32 = (studentId) => { return new Student(); }
};
Zwróć uwagę, że w przykładzie MS Fakes tworzysz zupełnie nową implementację metody DoesStudentExist (zwróć uwagę, że nazywa się ona DoesStudentExistInt32, ponieważ fałszywa struktura dodaje typy danych parametrów do nazw metod podczas generowania obiektów pośredniczących. Myślę, że to przesłania przejrzystość testy). Szczerze mówiąc, implementacja NMock również mnie niepokoi, ponieważ używa łańcucha do identyfikacji nazwy metody. (Wybacz mi, jeśli źle zrozumiałem, w jaki sposób ma być używany NMock.) To podejście naprawdę hamuje refaktoryzację iz tego powodu gorąco polecam RhinoMocks lub Moq zamiast NMock.
Mocks: Mocks służy do weryfikacji interakcji między testowaną metodą a jej zależnościami. W NMock możesz to zrobić, ustawiając oczekiwania podobne do tego:
Expect.Once.On(mockStudentRepository).Method("Find").With(123);
Jest to kolejny powód, dla którego wolałbym RhinoMocks i Moq od NMock, NMock używa starszego stylu oczekiwania, podczas gdy RhinoMocks i Moq obsługują podejście Arrange / Act / Assert, w którym określasz oczekiwane interakcje jako asercje na końcu takiego testu :
stubStudentRepository.AssertWasCalled( x => x.Find(123));
Ponownie zwróć uwagę, że RhinoMocks używa lambda zamiast ciągu do identyfikacji metody. Frameworka MS Fakes w ogóle nie udostępnia makiet. Oznacza to, że w twoich odgałęzionych implementacjach (zobacz opis pośredników powyżej) musisz ustawić zmienne, które później sprawdzisz, że zostały ustawione poprawnie. To wyglądałoby mniej więcej tak:
bool wasFindCalled = false;
IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository()
{
DoesStudentExistInt32 = (studentId) =>
{
wasFindCalled = true;
return new Student();
}
};
classUnderTest.MethodUnderTest();
Assert.IsTrue(wasFindCalled);
Uważam, że to podejście jest trochę zawiłe, ponieważ musisz śledzić wywołanie w odgałęzieniu, a następnie potwierdzić je później w teście. Uważam, że przykłady NMock, a zwłaszcza RhinoMocks, są bardziej wyraziste.
Krety (podkładki): Szczerze mówiąc, nie lubię pieprzyków ze względu na ich możliwość niewłaściwego użycia. Jedną z rzeczy, które tak bardzo lubię w testach jednostkowych (a zwłaszcza TDD) jest to, że testowanie kodu pomaga zrozumieć, gdzie napisałeś kiepski kod. Dzieje się tak, ponieważ testowanie źle napisanego kodu jest trudne. Nie jest to prawdą w przypadku używania moli, ponieważ mole są tak naprawdę zaprojektowane, aby umożliwić testowanie pod kątem zależności, które nie są wstrzykiwane, lub testowanie metod prywatnych. Działają podobnie do stubów, z wyjątkiem tego, że używasz ShimsContext w następujący sposób:
using (ShimsContext.Create())
{
System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(fixedYear, 1, 1); };
}
Martwię się, że ludzie zaczną postrzegać je jako „łatwiejszy sposób na testowanie jednostkowe”, ponieważ nie zmusza to do pisania kodu tak, jak powinieneś. Aby uzyskać pełniejszy opis tej koncepcji, zobacz mój post:
Aby uzyskać więcej informacji na temat niektórych problemów związanych z fałszywymi ramami, zapoznaj się z tymi postami:
Jeśli jesteś zainteresowany nauką RhinoMocks, oto film szkoleniowy Pluralsight (pełne ujawnienie - napisałem ten kurs i otrzymuję tantiemy za wyświetlenia, ale myślę, że dotyczy to tej dyskusji, więc dołączam to tutaj):