2011-12-22 8 views
8

Używam Moq do testowania zachowania niektórych metod void. Przy każdym połączeniu z próbą należy podać krok Arrange. Powoduje to wiele testów, które nie mają żadnego kroku Assert (lub Verify). Warunek przejścia jest po prostu taki, że test został uruchomiony bez wyjątku. Czy czegoś brakuje? Czy wzorzec Arrange, Act, Assert jest nieodpowiedni przy stosowaniu rygorystycznych makiet? Czy istnieje bardziej semantyczny sposób rozmieszczenia tych testów?TDD Rozmieść akt Wzorzec assert podczas korzystania z Mocks w celu sprawdzenia wywołań zależności

Trywialny składa się przykładem ...

[TestClass] 
public void DeleteUser_ShouldCallDeleteOnRepository() 
{ 
    // Arrange 
    var userRepository = new Mock<IUserRepository>(MockBehavior.Strict); 

    int userId = 9; 
    userRepository.Setup(x => x.Delete(userId)); 

    var controller = new UserController(userRepository.Object); 

    // Act 
    controller.DeleteUser(userId); 

    // Assert 
    // ...? 
} 
+0

Co się stanie, jeśli test zapisany nie powiedzie się (funkcja Repository.delete() nie jest wywoływana)? Czy komunikat o błędzie jest jasny? Jeśli tak, powiedziałbym, że nie trzeba tego zmieniać. –

Odpowiedz

22

Twój makiety jest zajmując miejsce współpracownik. Jest idealnie robi jedną z dwóch rzeczy:

  • Dostarczanie informacji lub danych
  • wykonuje pracę

Gdy makiety jest dostarczanie informacji lub danych, to wystarczy, że powinno to być stub. Możesz ustawić wartość zwracaną przez próbę na wymagane informacje. To powinno być częścią Rozmieść.

Gdy próbna wykonuje pracę, delegacja może być zweryfikowana. Właśnie dlatego masz Assert.

To, co robisz ze ścisłą interakcją, zapewnia oczekiwanie na każdą interakcję, mówiąc w zasadzie: "Oto, czego się spodziewam, a jeśli cokolwiek innego się stanie, to jest źle". To jest inny rodzaj testowania do działania, aranżacji, asercji, który mówi: "w tym kontekście, kiedy robię te rzeczy, powinienem otrzymać taki wynik."

Przy pomocy "miłej" sztuczki musisz się tylko martwić o interakcje, które Cię interesują. Na przykład, jeśli jestem kontrolerem i szukam informacji w jednym repozytorium, sprawdzam to. z walidatora, a następnie zapisując wynik w innym repozytorium, mogę mieć kilka testów:

  • jeden, by sprawdzić, że jestem walidacji przed właściwym informacji
  • jeden, by sprawdzić, jak mam reagować na błędnej walidacji
  • i jeden, aby sprawdzić, czy zapiszę przedmiot.

Dzięki ścisłej mock, trzeba zrobić wszystkie oczekiwania, nawet jeśli wszystko jesteś zainteresowany jest „zapisz”. Korzystając z fajnej sztuczki, możemy podzielić różne aspekty zachowania i skupić się tylko na jednym z nich w każdym teście.

Jako dodatkowy bonus, ładne mocks pozwalają zrobić:

  • Biorąc pod uwagę kontekst
  • Gdy to zdarzenie
  • Wtedy ten wynik powinien wystąpić

Zważywszy surowe mocks zrobić Ty:

  • Given kontekst
  • spodziewać się pewnych rzeczy się wydarzy
  • Kiedy wykonać wydarzenie
  • Następnie wróć i przeczytaj co wynik powinien być rzeczywiście.

Pierwsza z nich jest ogólnie uważana za bardziej czytelną.

+1

OK, że interesujące. Aby upewnić się, że zrozumiałem cię poprawnie, zaleca się, aby nie używać "MockBehavior.Strict", ale zamiast tego używał jawnie polecenia Verify? – fearofawhackplanet

+2

Tak, właśnie to byłbym zwolennikiem (i dlatego stworzono "ładne" szydercze ramy, takie jak Moq). Zauważ, że nadal będziesz musiał skonfigurować wszystkie mocks, które dostarczają informacji - ale wielką rzeczą jest to, że możesz teraz to zrobić * bez względu na to, czy zostanie wywołany, czy nie *. – Lunivore

+1

+1, aby uzyskać jasną i przekonującą odpowiedź. –

Powiązane problemy