Jaki jest najlepszy sposób testowania jednostkowego metody, która nic nie zwraca? W szczególności w języku C #.
To, co naprawdę próbuję przetestować, to metoda, która pobiera plik dziennika i analizuje go pod kątem określonych ciągów. Ciągi są następnie wstawiane do bazy danych. Nic, czego nie zrobiono wcześniej, ale będąc BARDZO nowością w TDD, zastanawiam się, czy można to przetestować, czy jest to coś, co tak naprawdę nie jest testowane.
c#
unit-testing
jdiaz
źródło
źródło
Odpowiedzi:
Jeśli metoda nic nie zwraca, jest to jedna z poniższych
Metody rozkazujące - możesz sprawdzić, czy zadanie zostało faktycznie wykonane. Sprawdź, czy rzeczywiście nastąpiła zmiana stanu. na przykład
można sprawdzić, sprawdzając, czy saldo zaksięgowane w tej wiadomości jest rzeczywiście mniejsze niż początkowa wartość dAmount
Metody informacyjne - są rzadkie jako element interfejsu publicznego obiektu ... stąd normalnie nie są testowane jednostkowo. Jeśli jednak musisz, możesz sprawdzić, czy ma miejsce obsługa zgłoszenia. na przykład
można przetestować, sprawdzając, czy wiadomość e-mail jest wysyłana
Opublikuj więcej szczegółów na temat swojej faktycznej metody, a ludzie będą mogli lepiej odpowiedzieć.
Aktualizacja : Twoja metoda robi 2 rzeczy. Właściwie podzieliłbym to na dwie metody, które można teraz niezależnie przetestować.
Ciąg [] można łatwo zweryfikować, podając pierwszą metodę z fikcyjnym plikiem i oczekiwanymi ciągami. Drugi jest nieco trudny. Możesz albo użyć Mocka (Google lub Search stackoverflow na frameworkach do naśladowania), aby naśladować bazę danych lub trafić do rzeczywistej bazy danych i sprawdzić, czy ciągi znaków zostały wstawione we właściwym miejscu. Sprawdź ten wątek, aby znaleźć dobre książki ... Polecam Pragmatic Unit Testing, jeśli jesteś w kryzysie.
W kodzie byłby używany jak
źródło
Przetestuj jego skutki uboczne. To zawiera:
Oczywiście istnieje limit tego, ile możesz przetestować. Na przykład generalnie nie można testować z każdym możliwym wejściem. Testuj pragmatycznie - na tyle, aby mieć pewność, że Twój kod jest odpowiednio zaprojektowany i poprawnie zaimplementowany oraz na tyle, aby działać jako dodatkowa dokumentacja dla tego, czego może oczekiwać rozmówca.
źródło
Jak zawsze: sprawdź, co ma robić metoda!
Czy powinien gdzieś zmienić stan globalny (uuh, zapach kodu!)?
Czy powinien wywołać interfejs?
Czy powinien zgłosić wyjątek, gdy zostanie wywołany z niewłaściwymi parametrami?
Czy powinien zgłaszać żaden wyjątek, gdy zostanie wywołany z odpowiednimi parametrami?
Czy powinno ...?
źródło
Void zwracane typy / podprogramy to stare wiadomości. Nie wykonałem zwrotu typu Void (chyba, że byłem wyjątkowo leniwy) od 8 lat (od czasu tej odpowiedzi, a więc trochę przed tym pytaniem).
Zamiast metody takiej jak:
Utwórz metodę zgodną z paradygmatem int.TryParse () firmy Microsoft:
Być może nie ma żadnych informacji, które Twoja metoda musiałaby zwrócić do użycia na dłuższą metę, ale zwracanie stanu metody po jej wykonaniu jest bardzo przydatne dla wywołującego.
Ponadto bool nie jest jedynym typem stanu. Wiele razy poprzednio utworzona podprocedura mogła w rzeczywistości zwrócić trzy lub więcej różnych stanów (dobry, normalny, zły itp.). W takich przypadkach po prostu użyjesz
Jednak podczas gdy Try-Paradigm w pewnym stopniu odpowiada na to pytanie, jak przetestować zwrot z pustej przestrzeni, istnieją również inne kwestie. Na przykład, podczas / po cyklu „TDD”, będziesz „refaktoryzować” i zauważysz, że robisz dwie rzeczy swoją metodą… łamiąc w ten sposób „zasadę pojedynczej odpowiedzialności”. Więc najpierw należy się tym zająć. Po drugie, mogłeś zidentyfikować zależność ... dotykasz „Trwałe” dane.
Jeśli zajmujesz się dostępem do danych w metodzie, o której mowa, musisz dokonać refaktoryzacji w architekturę n-warstwową lub n-warstwową. Ale możemy założyć, że kiedy mówisz „Ciągi znaków są następnie wstawiane do bazy danych”, w rzeczywistości masz na myśli wywołanie warstwy logiki biznesowej lub coś w tym rodzaju. Tak, założymy, że.
Kiedy tworzony jest obiekt, rozumiesz teraz, że obiekt ma zależności. To wtedy musisz zdecydować, czy zamierzasz wykonać Dependency Injection na obiekcie, czy na metodzie. Oznacza to, że Twój Konstruktor lub metoda, o której mowa, potrzebuje nowego parametru:
Teraz, gdy możesz zaakceptować interfejs obiektu warstwy biznesowej / danych, możesz wyszydzać go podczas testów jednostkowych i nie mieć żadnych zależności ani obawiać się „przypadkowych” testów integracji.
Więc w swoim aktywnym kodzie przekazujesz PRAWDZIWY
IBusinessDataEtc
obiekt. Ale w testach jednostkowych przekazujeszIBusinessDataEtc
obiekt MOCK . W tym makiecie można dołączyć właściwości niezwiązane z interfejsem, takie jakint XMethodWasCalledCount
lub coś, czego stan (y) są aktualizowane, gdy wywoływane są metody interfejsu.Więc twój test jednostkowy przejdzie przez twoją metodę (y) -w pytaniu, wykona jakąkolwiek logikę, którą ma i wywoła jedną lub dwie lub wybrany zestaw metod w twoim
IBusinessDataEtc
obiekcie. Kiedy wykonujesz swoje asercje na koniec testu jednostkowego, masz teraz kilka rzeczy do przetestowania.IBusinessDataEtc
obiektu Mock .Aby uzyskać więcej informacji na temat pomysłów na iniekcję zależności na poziomie konstrukcji ... w odniesieniu do testów jednostkowych ... zapoznaj się z wzorcami projektowymi programu Builder. Dodaje jeszcze jeden interfejs i klasę dla każdego aktualnego interfejsu / klasy, ale są one bardzo małe i zapewniają OGROMNY wzrost funkcjonalności dla lepszego testowania jednostek.
źródło
public void sendEmailToCustomer() throws UndeliveredMailException
?void
metodach, zwłaszcza w językach zorientowanych obiektowo, była to jedyna prawdziwa opcja. Najstarszą alternatywą Microsoftu jest Try-Paradigm, o którym mówię, oraz paradygmaty w stylu funkcjonalnym, takie jak Monads / Maybes. W ten sposób polecenia (w CQS) mogą nadal zwracać cenne informacje o statusie zamiast polegać na rzucaniu, co jest podobne doGOTO
(co wiemy, że jest złe). rzucanie (i goto) jest powolne, trudne do debugowania i nie jest dobrą praktyką.Spróbuj tego:
źródło
ExpectedAttribute
na celu uczynienie tego testu jaśniejszym.Możesz nawet spróbować w ten sposób:
źródło
będzie miało jakiś wpływ na obiekt ... Zapytanie o wynik efektu. Jeśli nie ma widocznego efektu, nie warto go testować jednostkowo!
źródło
Przypuszczalnie metoda coś robi i po prostu nie wraca?
Zakładając, że tak jest, to:
Jeśli dasz nam znać, co robi ta metoda, mogę być bardziej szczegółowy.
źródło
Użyj Rhino Mocks, aby określić, jakich wywołań, akcji i wyjątków można się spodziewać. Zakładając, że możesz kpić lub ignorować części swojej metody. Trudno to wiedzieć bez znajomości szczegółów dotyczących metody, a nawet kontekstu.
źródło
Zależy od tego, co robi. Jeśli ma parametry, przekaż makiety, o które możesz zapytać później, czy zostały wywołane z odpowiednim zestawem parametrów.
źródło
Niezależnie od instancji, której używasz do wywołania metody void, możesz po prostu użyć,
Verfiy
Na przykład:
W moim przypadku
_Log
jest to instancja iLogMessage
metoda do przetestowania:Czy
Verify
zgłasza wyjątek z powodu niepowodzenia metody, której test się nie powiedzie?źródło