C #: Как я могу проверить «не произошло исключение» в моем модульном тесте MSTest? - PullRequest
67 голосов
/ 23 февраля 2012

Я пишу модульный тест для этого метода, который возвращает "void". Я хотел бы иметь один случай, когда тест проходит, когда не было выброшено исключение. Как мне написать это в C #?

Assert.IsTrue(????)

(я думаю, это то, как я должен проверить, но что входит в "???")

Надеюсь, мой вопрос достаточно ясен.

Ответы [ 6 ]

110 голосов
/ 23 февраля 2012

Ваш юнит-тест в любом случае не пройдёт, если возникнет исключение - вам не нужно вводить специальное утверждение.

Это один из немногих сценариев, где вы увидите модульные тесты без каких-либо утверждений - тест неявно завершится неудачей, если возникнет исключение.

Однако, если вы действительно хотите написать утверждение для этого - возможно, чтобы иметь возможность перехватить исключение и сообщить «не ожидал исключения, но получил это ...», вы можете сделать это:

[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
    var myObject = new MyObject();

    try
    {
        myObject.MethodUnderTest();
    }
    catch (Exception ex)
    {
        Assert.Fail("Expected no exception, but got: " + ex.Message);
    }
}

(приведенный выше пример для NUnit, но то же самое относится и к MSTest)

23 голосов
/ 14 апреля 2014

В NUnit вы можете использовать:

Assert.DoesNotThrow(<expression>); 

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

Я думаю, что правильно добавлять тесты, чтобы убедиться, что ваш код не вызывает исключений;например, представьте, что вы проверяете ввод и вам нужно преобразовать входящую строку в long.Могут быть случаи, когда строка имеет значение null, и это приемлемо, поэтому необходимо убедиться, что преобразование строки не вызывает исключение.Поэтому будет код для обработки этого случая, и если вы не написали тест для него, вам будет не хватать освещения вокруг важной части логики.

11 голосов
/ 23 февраля 2012

Не проверяйте, что что-то не происходит . Это все равно что гарантировать, что код не сломается . Это как бы подразумевается, мы все стремимся к не ломающемуся, без ошибок коду. Вы хотите написать тесты для этого? Почему только один метод? Разве вы не хотите, чтобы все ваши методы были протестированы, чтобы они не выдавали исключений ? Следуя этому пути, вы получите один дополнительный, фиктивный тест без утверждения для каждого метода в вашей кодовой базе. Это не приносит никакой ценности.

Конечно, если ваше требование заключается в проверке метода , перехватывает исключения , вы проверяете это (или немного меняете его; проверяете, что он не выбрасывает то, что предполагается поймать).

Тем не менее, общий подход / методы остаются неизменными - вы не пишете тесты для некоторых искусственных / расплывчатых требований, которые выходят за рамки тестируемого кода (и тестирование, что «это работает» или «не выбрасывает», обычно пример такого - особенно в сценарии, когда обязанности метода хорошо известны).

Проще говоря - сфокусируйтесь на том, что ваш код должен сделать и проверьте это.

5 голосов
/ 17 августа 2016

Этот вспомогательный класс почесал мой зуд с помощью MSTest.Может быть, это может поцарапать и тебя тоже.

[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);
        }
    }
}
2 голосов
/ 04 марта 2017

Мне нравится видеть Assert.Whatever в конце каждого теста, просто для согласованности ... без одного, могу ли я быть действительно уверен, что там не должно быть ни одного?

Для меня этотак же просто, как поставить Assert.IsTrue(true);

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

    [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

    }
0 голосов
/ 31 мая 2019

Мой друг Тим рассказал мне о ExpectedException . Мне очень нравится этот б / с, он более лаконичен, меньше кода и очень явный, что вы тестируете на предмет исключения.

[TestMethod()]
[ExpectedException(typeof(System.Exception))]
public void DivideTest()
{
    int numerator = 4;
    int denominator = 0;
    int actual = numerator / denominator;
}

Подробнее об этом можно прочитать здесь: Использование атрибутов ExpectedException .

...