Проверка ArgumentException и его сообщение в Nunit, С#

В моей тестовой программе в Nunit, я хочу проверить, что она получает сообщение Argument Exception, проверяя сообщение.

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

    }

После проверки этого, это не сработает, когда я изменил сообщение в основной программе.

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

unit test все еще прошел, независимо от того, изменил ли я сообщение.

Как мне это сделать? Или нет таких вещей в С#. Мой коллега сказал, что есть такие варианты в Ruby и RSPEC, но он не уверен на 100% на С#.

Ответы

Ответ 1

Используйте свободный интерфейс для создания утверждений:

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

Ответ 2

Я согласен с Джоном в том, что "такие тесты излишне хрупкие". Однако есть, по крайней мере, два способа проверить сообщение об ошибке:

1: Assert.Throws возвращает исключение, поэтому вы можете сделать утверждение для своего сообщения:

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

2: Вы также можете использовать атрибут ExpectedException. Но обратите внимание, что атрибут ожидает исключения во всем тестированном коде, а не только в коде, который выдает исключение, кроме вас. Таким образом, использование этого атрибута не рекомендуется.

[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

Параметр сообщения в Assert.Throws не является ожидаемым сообщением об исключении; это сообщение об ошибке должно включать с ошибкой утверждения, если тест не выполняется.

Я не считаю, что NUnit поддерживает тестирование сообщения об исключении из коробки, и я бы сказал, что такие тесты излишне хрупкие. Если вы действительно хотите написать свой собственный такой вспомогательный метод, вы можете сделать это, но я лично не буду его поощрять. (Я очень редко указываю сообщение об ошибке тестирования, если оно не содержит некоторую диагностическую информацию. Если тест не удается, я все равно посмотрю на тест, поэтому сообщение не добавляет много.)

Я бы рекомендовал использовать вместо этого общую перегрузку, а также выражение лямбда для простоты:

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

(Если ваш фактический код, кстати, есть другие проблемы - попробуйте передать new[] { "xyz" } в качестве аргумента...)