2013-07-23 14 views
17

W moim programie testowym w Nunit, chcę sprawdzić, czy otrzymuje on wyjątek argumentu Argument, sprawdzając komunikat.Sprawdzanie wyjątku ArgumentException i jego komunikatu w Nunit, C#

[Test] 
    public void ArgumentsWorkbookNameException() 
    { 
     const string workbookName = "Tester.xls"; 
     var args = new[] { workbookName, "Sheet1", "Source3.csv", "Sheet2", "Source4.csv" }; 
     Assert.Throws(typeof(ArgumentException), delegate { var appargs = new ApplicationArguments(args); }, "Invalid ending parameter of the workbook. Please use .xlsx"); 

    } 

Po przetestowaniu tego nie działa, gdy zmodyfikowałem komunikat w programie głównym.

 int wbLength = args[0].Length; 

     // Telling the user to type in the correct workbook name file. 
     if (args[0].Substring(wbLength-5,5)!=".xlsx") 
     { 
      throw new ArgumentException(
       "Invalid ending parameter of the workbook. Please use .xlsx random random"); 
     } 

Test urządzenia nadal przebiegał pomyślnie, niezależnie od tego, czy zmieniłem komunikat.

Jak to zrobić? Czy nie ma takich rzeczy w języku C#. Mój kolega powiedział, że są takie opcje w Ruby i RSPEC, ale nie jest w 100% pewny w C#.

Odpowiedz

3

Parametr komunikatu w Assert.Throws nie jest oczekiwanym komunikatem wyjątku; jest to komunikat o błędzie dołączany z niepowodzeniem asercji, jeśli test się nie powiedzie.

Nie wierzę, że NUnit obsługuje testowanie komunikatu wyjątku po wyjęciu z pudełka, i twierdzę, że takie testy są niepotrzebnie kruche. Jeśli naprawdę chcesz napisać własną metodę pomocniczą, możesz to zrobić, ale ja osobiście nie zachęciłbym tego. (Bardzo rzadko określam komunikat o niepowodzeniu testu, chyba że ma on zawierać pewne informacje diagnostyczne.Jeśli test zakończy się niepowodzeniem, to i tak sprawdzę test, więc wiadomość nie doda wiele.)

I byłoby zachęcamy do korzystania z rodzajowe przeciążenie zamiast choć i wyrażenia lambda, dla uproszczenia:

Assert.Throws<ArgumentException>(() => new ApplicationArguments(args)); 

(Jeśli to rzeczywisty kod nawiasem mówiąc, są inne problemy - spróbuj przechodząc new[] { "xyz" } jako argument. ..)

+1

ale czy nie warto zweryfikować, sprawdzając wiadomość, że wyjątek testujesz jest jeden chcesz, a nie inny w inny punkt twojego kodu? Jeśli ten sam typ wyjątku, ale z innego miejsca, może twój kod robi coś, czego nie chcesz. – Riga

+0

@Riga: Możesz, jeśli chcesz - ale nie uważam, żeby to było warte mojego czasu. Lubię addaż "testu, aż strach zamieni się w nudę". Byłbym bardzo znudzony testowaniem * dokładnego * komunikatu wyjątku, a następnie zmienianie testów za każdym razem, gdy chciałem uczynić ten wyjątek bardzo nieznacznie bardziej informatywnym itd. Więc chociaż nie uważam tego za użyteczny, twój przebieg może się różnić . –

+1

Alternatywą jest przechowywanie stałych we wspólnej lokalizacji lub klasie, a kod produkcyjny i testowy muszą wskazywać to samo miejsce. Jeśli wiadomość musi się kiedykolwiek zmienić, po prostu zmień ją w tej jednej lokalizacji. – neverendingqs

12

Zgadzam się z Jonem, że "takie testy są niepotrzebnie kruche". Jednak istnieją przynajmniej dwa sposoby, aby sprawdzić wiadomości wyjątek:

1: Assert.Throws zwraca wyjątek, aby można było twierdzenie o jej przesłanie:

var exception = Assert.Throws<ArgumentException>(() => new ApplicationArguments(args)); 
Assert.AreEqual("Invalid ending parameter of the workbook. Please use .xlsx random random", exception.Message); 

2: Można również użyć Atrybut ExpectedException. Należy jednak pamiętać, że atrybut oczekuje na wyjątek w całym testowanym kodzie, nie tylko w kodzie, który zgłasza wyjątek. Dlatego używanie tego atrybutu nie jest zalecane.

[Test] 
[ExpectedException(typeof(ArgumentException), ExpectedMessage = "Invalid ending parameter of the workbook. Please use .xlsx random random")] 
public void ArgumentsWorkbookNameException() 
{ 
    const string workbookName = "Tester.xls"; 
    var args = new[] { workbookName, "Sheet1", "Source3.csv", "Sheet2", "Source4.csv" }; 
    new ApplicationArguments(args); 
} 
+3

Osobiście uniknęłbym 'ExpectedExceptionAttribute'. 'Assert.Throws' wyjaśnia, gdzie * dokładnie * wystąpił błąd. Jeśli OP * naprawdę * chce przetestować komunikat wyjątku, lepiej byłoby napisać własne "MoreAsersesions.Throws" lub cokolwiek innego. –

+0

@JonSkeet: Rzeczywiście, wyjaśniłem o tym atrybucie. –

35

Użyj biegle interfejs do tworzenia twierdzeń:

Assert.That(() => new ApplicationArguments(args), 
    Throws.TypeOf<ArgumentException>() 
     .With.Message.EqualTo("Invalid ending parameter of the workbook. Please use .xlsx random random")); 
+0

Asercje płynne wydają się być dodatkiem open source dla NUnit, a podsumowanie znajduje się pod adresem https://lukewickstead.wordpress.com/2013/02/09/howto-nunit-fluent-assertions/ . Źródło znajduje się pod adresem https://github.com/mvbalaw/FluentAssert –

Powiązane problemy