Ошибка MSTest ExpectedException
Обычно я использую Nunit, но в моем текущем проекте я использую MSTest. Теперь у меня есть тест, который ожидает исключения, но продолжает терпеть неудачу, и я не знаю, почему.
Вот простой пример, который я использовал для репликации проблемы:
[TestMethod, ExpectedException(typeof(ErrorResponseException))]
public void should_throw_exception()
{
throw new ErrorResponseException();
}
Ошибка ErrorResponseException - это класс, который просто наследуется от Exception, то есть кто-нибудь знает, почему это терпит неудачу, я бы ожидал, что он пройдет.
Ответы
Ответ 1
В NUnit я бы избегал ExpectedException и вместо этого использовал Assert.Throws(Exception Asserts). Это дает вам более тонкий контроль. В противном случае тест пройдет, если какая-либо часть тестового метода выдает это исключение.
В MSTest вы можете получить тот же уровень контроля со структурой старой школы:
try
{
// code that you expect to throw goes here
Assert.Fail("Expected MyException");
}
catch (MyException ex)
{
// optionally assert on the message - this can make tests fragile though
}
При этом нет необходимости в атрибуте ExpectedException.
(Концепция взята из книги "Испытательное развитие: практическое руководство" Дэвида Астелса.)
Ответ 2
Бесстыдный плагин, но я написал простую сборку, которая делает утверждение для исключений и сообщений об исключениях более легким и читаемым в MSTest с использованием синтаксиса Assert.Throws(). Я написал сообщение в блоге с полной информацией.
Ответ 3
Если вы используете MSTest 10.0.1.0.0, ExpectedException, похоже, работает некорректно, вместо этого используйте 10.0.0.0.0.
Ответ 4
У меня была такая же проблема, и я нашел другое решение. Мой метод тестирования был async
, но я забыл ключевое слово await
для вызова в моем тестовом методе.
Тест:
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ShouldDoSomething(){
// notice the missing await in the next line
this.testObject.DoSomethingAsync();
}
Метод тестирования:
public async Task<bool> DoSomethingAsync(){
if(something)
{
throw new InvalidOperationException("Error while doing something");
}
return false;
}
Когда я запускал свой тест, как это, он потерпел неудачу. Но как только я сменил тест на следующее:
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ShouldDoSomething(){
await this.testObject.DoSomethingAsync();
}
это сработало для меня.
Ответ 5
В Visual Studio 15
с зависимостями от MSTest.TestAdapter v1.1.18
и MSTest.TestFramework v1.1.18
вы также можете использовать
Assert.ThrowsException<ArgumentNullException>(() => MethodThatThrowsArgumentNullException());
Ответ 6
ExpectedExceptionAttribute теперь определен в нескольких DLL, а бегун unit test может ожидать, что атрибут из другой DLL будет использоваться в том, который использует ваш тестовый проект.
В качестве примера я создал проект unit test в VS2017 и получил ExpectedException из Microsoft.VisualStudio.TestPlatform.TestFramework V14.0.0.0 - тест проходит в среде IDE, но сбой в TeamCity, даже если используется VSTest бегун на версии 2017.
В итоге я получил его в TeamCity, удалив все ссылки на эту DLL в моих тестовых проектах и заменив их версией 10.0.0.0 Mirosoft.VisualStudio.QualityTools.UnitTestFramework