web-dev-qa-db-fra.com

Vérification de ArgumentException et de son message dans Nunit, C #

Dans mon programme de test dans Nunit, je veux vérifier qu'il obtient l'exception d'écriture d'argument en vérifiant le message.

    [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");

    }

Après avoir testé cela, cela ne fonctionne pas lorsque j'ai modifié le message dans le programme principal.

        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");
        }

Le test unitaire a quand même réussi, peu importe si j'ai changé le message.

Comment fait-on ça? Ou n'y a-t-il pas de telles choses en C #. Mon collègue a dit qu'il y avait des options comme ça dans Ruby et RSPEC, mais il n'est pas sûr à 100% sur C #.

31
Henry Zhang

Utilisez l'interface fluide pour créer des assertions:

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

Je suis d'accord avec Jon que "ces tests sont inutilement fragiles". Cependant, il existe au moins deux façons de rechercher un message d'exception:

1: Assert.Throws renvoie une exception, vous pouvez donc faire une assertion pour son message:

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

2: Vous pouvez également utiliser l'attribut ExpectedException . Mais, notez que l'attribut attend une exception dans tout le code testé, non seulement dans le code qui lève une exception, sauf vous. Par conséquent, l'utilisation de cet attribut n'est pas recommandée.

[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);
}
24
Dariusz Woźniak

Le paramètre de message dans Assert.Throws n'est pas le message d'exception attendu; c'est le message d'erreur à inclure avec l'échec de l'assertion si le test échoue.

Je ne crois pas que NUnit supporte de tester le message d'exception hors de la boîte, et je dirais que ces tests sont de toute façon inutilement fragiles. Si vous vraiment voulez écrire votre propre méthode d'aide, vous pouvez le faire, mais personnellement je ne l'encouragerais pas. (Je spécifie très rarement un message d'échec de test non plus, sauf s'il s'agit d'inclure des informations de diagnostic. Si un test échoue, je vais quand même regarder le test, donc le message n'ajoute pas grand-chose.)

Je voudrais vous encourage à utiliser à la place la surcharge générique et une expression lambda, pour plus de simplicité:

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

(Si c'est votre code actuel, il y a d'autres problèmes - essayez de passer new[] { "xyz" } comme argument ...)

4
Jon Skeet