У меня есть несколько разных шаблонов, которые я использую. Я использую ExpectedException
атрибут чаще всего, когда ожидается исключение. Этого достаточно для большинства случаев, однако бывают случаи, когда этого недостаточно. Исключение может быть невозможно перехватить - поскольку оно вызывается методом, вызываемым отражением, - или, возможно, я просто хочу проверить, выполняются ли другие условия, например, откат транзакции или какое-то значение все еще установлено. В этих случаях я помещаю его в try/catch
блок, который ожидает точное исключение, выполняет Assert.Fail
ли код, если код завершается успешно, а также перехватывает общие исключения, чтобы убедиться, что другое исключение не сгенерировано.
Первый случай:
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MethodTest()
{
var obj = new ClassRequiringNonNullParameter( null );
}
Второй случай:
[TestMethod]
public void MethodTest()
{
try
{
var obj = new ClassRequiringNonNullParameter( null );
Assert.Fail("An exception should have been thrown");
}
catch (ArgumentNullException ae)
{
Assert.AreEqual( "Parameter cannot be null or empty.", ae.Message );
}
catch (Exception e)
{
Assert.Fail(
string.Format( "Unexpected exception of type {0} caught: {1}",
e.GetType(), e.Message )
);
}
}
Assert.Throws
метод, который охватывает оба этих случая.Теперь, в 2017 году, вы можете сделать это проще с новой MSTest V2 Framework :
источник
System.Exception
будет брошено. Любой другой, например, неSystem.ArgumentException
пройдёт тест.Assert.ThrowsException<MyException>
будет проверяться исключительно предоставленный тип исключения, а не какие-либо производные от него типы исключений. В моем примере, если тестируемоеSub
былThrow
вMyInheritedException
(производный тип из базового классаMyException
), то тест будет терпеть неудачу .Try { SubToTest(); Assert.Fail("...") } Catch (AssertFailedException e) {throw;} Catch (MyException e) {...}
. Обратите внимание на первостепенную важностьCatch (AssertFailedException e) {throw;}
(см. Комментарий allgeek)Я здесь новичок и у меня нет репутации, чтобы комментировать или отрицать, но я хотел указать на ошибку в примере в ответе Энди Уайта :
Во всех фреймворках модульного тестирования, с
Assert.Fail
которыми я знаком, они генерируют исключение, поэтому общий улов фактически маскирует неудачу теста. ЕслиSomethingThatCausesAnException()
не бросает,Assert.Fail
будет, но никогда не выйдет из-под контроля бегуна, чтобы указать на сбой.Если вам нужно перехватить ожидаемое исключение (т. Е. Подтвердить определенные детали, такие как сообщение / свойства исключения), важно перехватить конкретный ожидаемый тип, а не базовый класс Exception. Это позволит
Assert.Fail
исключению всплыть (при условии, что вы не генерируете тот же тип исключения, что и ваша платформа модульного тестирования), но все же разрешите проверку исключения, которое было создано вашимSomethingThatCausesAnException()
методом.источник
Начиная с версии 2.5, NUnit имеет следующие уровни методов
Assert
для тестирования исключений:Assert.Throws , который проверит точный тип исключения:
И
Assert.Catch
, который будет проверять исключение данного типа или типа исключения, производного от этого типа:Кроме того, при отладке модульных тестов, которые генерируют исключения, вы можете захотеть предотвратить прерывание VS при исключении .
редактировать
Чтобы привести пример комментария Мэтью ниже, возврат универсального
Assert.Throws
иAssert.Catch
является исключением с типом исключения, которое вы затем можете изучить для дальнейшей проверки:источник
Assert.Throws
, кроме того, он возвращает исключение, поэтому вы можете писать дальнейшие утверждения о самом исключении.К сожалению, MSTest STILL действительно имеет только атрибут ExpectedException (просто показывает, насколько MS заботится о MSTest), который IMO довольно ужасен, потому что он нарушает шаблон Arrange / Act / Assert и не позволяет вам точно указать, в какой строке кода вы ожидаете исключение происходить дальше.
Когда я использую (/ по принуждению клиента) использовать MSTest, я всегда использую этот вспомогательный класс:
Пример использования:
источник
В качестве альтернативы использованию
ExpectedException
атрибута я иногда определяю два полезных метода для своих тестовых классов:AssertThrowsException()
принимает делегата и утверждает, что он генерирует ожидаемое исключение с ожидаемым сообщением.AssertDoesNotThrowException()
принимает тот же делегат и утверждает, что он не создает исключения.Это соединение может быть очень полезным, если вы хотите проверить, что в одном случае возникает исключение, а в другом - нет.
Используя их, мой код модульного теста может выглядеть так:
Красиво и аккуратно, да?
My
AssertThrowsException()
иAssertDoesNotThrowException()
методы определены в общем базовом классе следующим образом:источник
В большинстве сред модульного тестирования .net вы можете поместить атрибут [ExpectedException] в метод тестирования. Однако это не может сказать вам, что исключение произошло в тот момент, когда вы этого ожидали. Вот где может помочь xunit.net .
С xunit у вас есть Assert.Throws, поэтому вы можете делать что-то вроде этого:
[Fact] - это xunit-эквивалент [TestMethod]
источник
Отметьте тест атрибутом ExpectedExceptionAttribute (это термин в NUnit или MSTest; пользователям других платформ модульного тестирования может потребоваться перевод).
источник
Предложить использовать NUnit чистый синтаксис делегата .
Пример для тестирования
ArgumentNullExeption
:источник