Ошибка 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