Piszę test jednostkowy dla tej metody, która zwraca „void”. Chciałbym mieć jeden przypadek, w którym test przechodzi pomyślnie, gdy nie został zgłoszony żaden wyjątek. Jak to napisać w C #?
Assert.IsTrue(????)
(Domyślam się, że tak powinienem sprawdzić, ale co wchodzi w skład „???”)
Mam nadzieję, że moje pytanie jest wystarczająco jasne.
c#
unit-testing
exception
mstest
Ciekawski George
źródło
źródło
Odpowiedzi:
Twój test jednostkowy i tak zakończy się niepowodzeniem, jeśli zostanie zgłoszony wyjątek - nie musisz umieszczać specjalnego potwierdzenia.
Jest to jeden z niewielu scenariuszy, w których zobaczysz testy jednostkowe bez żadnych asercji - test niejawnie zakończy się niepowodzeniem, jeśli zostanie zgłoszony wyjątek.
Jeśli jednak naprawdę chciałeś napisać asercję w tym celu - być może aby móc wychwycić wyjątek i zgłosić „nie spodziewałem się wyjątku, ale dostałem to ...”, możesz to zrobić:
[Test] public void TestNoExceptionIsThrownByMethodUnderTest() { var myObject = new MyObject(); try { myObject.MethodUnderTest(); } catch (Exception ex) { Assert.Fail("Expected no exception, but got: " + ex.Message); } }
(powyższe jest przykładem dla NUnit, ale to samo dotyczy MSTest)
źródło
W NUnit możesz użyć:
aby zapewnić, że Twój kod nie zgłasza wyjątku. Chociaż test zakończy się niepowodzeniem, jeśli wyjątek zostanie zgłoszony, nawet jeśli nie było wokół niego Assert, wartość tego podejścia polega na tym, że możesz następnie rozróżnić niespełnione oczekiwania i błędy w testach, a także masz możliwość dodania niestandardowego komunikatu, który zostanie wyświetlony w wyniku testu. Dobrze sformułowane wyniki testu mogą pomóc w zlokalizowaniu błędów w kodzie, które spowodowały niepowodzenie testu.
Myślę, że warto dodać testy, aby upewnić się, że kod nie wyrzuca wyjątków; na przykład wyobraź sobie, że sprawdzasz poprawność danych wejściowych i musisz przekonwertować przychodzący ciąg na długi. Mogą wystąpić sytuacje, w których ciąg ma wartość null i jest to akceptowalne, więc chcesz się upewnić, że konwersja ciągu nie zgłosi wyjątku. Będzie zatem kod, który poradzi sobie z tą sytuacją, a jeśli nie napisałeś dla niego testu, stracisz pokrycie ważnej części logiki.
źródło
public class TestBase { //believe me, I don't like this anymore than you do. protected void AssertDoesNotThrow(Action action, string message) { try { action(); } catch (Exception) { Assert.Fail(message); } } }
Nie sprawdzaj, czy coś się nie dzieje . To jak zapewnienie, że kod się nie psuje . To trochę zasugerowane, wszyscy dążymy do nierozerwalnego, pozbawionego błędów kodu. Chcesz napisać testy? Dlaczego tylko jedna metoda? Czy nie chcesz, aby wszystkie twoje metody były testowane, aby nie rzucały wyjątków ? Podążając tą drogą, otrzymasz jeden dodatkowy, fikcyjny, pozbawiony potwierdzenia test dla każdej metody w bazie kodu. Nie ma wartości.
Oczywiście, jeśli wymogiem jest, aby zweryfikować sposób robi wyjątki połowowe , zrobić test, który (lub odwrócenie go trochę, test, że nie rzuca to, co ma do połowu).
Jednak ogólne podejście / praktyki pozostają nienaruszone - nie piszesz testów dla niektórych sztucznych / niejasnych wymagań, które są poza zakresem testowanego kodu (a testowanie, czy „działa” lub „nie rzuca” jest zwykle przykładem takie - szczególnie w scenariuszu, w którym obowiązki metody są dobrze znane).
Mówiąc prościej - skoncentruj się na tym, co ma robić Twój kod i przetestuj to.
źródło
Ta klasa pomocnicza podrapała mnie po swędzeniu dzięki MSTest. Może to też może porysować twoje.
[TestMethod] public void ScheduleItsIneligibilityJob_HasValid_CronSchedule() { // Arrange var factory = new StdSchedulerFactory(); IScheduler scheduler = factory.GetScheduler(); // Assert AssertEx.NoExceptionThrown<FormatException>(() => // Act _service.ScheduleJob(scheduler) ); } public sealed class AssertEx { public static void NoExceptionThrown<T>(Action a) where T:Exception { try { a(); } catch (T) { Assert.Fail("Expected no {0} to be thrown", typeof(T).Name); } } }
źródło
Assert
ma pojedynczy element dostępu do właściwości,That
którego można użyć jako punktu zaczepienia dla metod rozszerzających. To może być schludniej i bardziej wykrywalne, abyAssert.That.DoesNotThrow()
zamiastAssertEx.DoesNotThrow()
. To tylko opinia.Lubię widzieć
Assert.Whatever
na końcu każdego testu, tylko dla spójności ... bez jednego, czy naprawdę mogę być pewien, że takiego nie powinno tam być?Dla mnie jest to tak proste, jak wprowadzenie
Assert.IsTrue(true);
Ja wiem, że nie przypadkowo umieścić ten kod tam, a zatem powinien być na tyle pewnie, a przy szybkim przejrzeć że to był zgodnie z przeznaczeniem.
[TestMethod] public void ProjectRejectsGappedVersioningByDefault() { var files = new List<ScriptFile>(); files.Add(ScriptProjectTestMocks.GetVersion1to2()); files.Add(ScriptProjectTestMocks.GetVersion3to4()); Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => { var sut = new ScriptProject(files); }); } [TestMethod] public void ProjectAcceptsGappedVersionsExplicitly() { var files = new List<ScriptFile>(); files.Add(ScriptProjectTestMocks.GetVersion1to2()); files.Add(ScriptProjectTestMocks.GetVersion3to4()); var sut = new ScriptProject(files, true); Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like }
źródło
Mój przyjaciel Tim powiedział mi o ExpectedException . Naprawdę podoba mi się ta b / c, jest bardziej zwięzła, mniej kodu i bardzo wyraźna, że testujesz pod kątem wyjątku.
[TestMethod()] [ExpectedException(typeof(System.Exception))] public void DivideTest() { int numerator = 4; int denominator = 0; int actual = numerator / denominator; }
Możesz przeczytać o wiele więcej na ten temat tutaj: ExpectedException Attribute Usage .
źródło