Не ожидаемые исключения - PullRequest
       70

Не ожидаемые исключения

49 голосов
/ 04 августа 2010

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

[ExpectedException("System.NullReferenceException")]

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

Я знаю, что есть также методы Assert.Throws<> и Assert.Throws, которые предлагает NUnit.

У меня вопрос, как я могу использовать их вместо атрибута, который я сейчас использую?

Я осмотрел StackOverflow и попробовал несколько вещей, ни одна из которых мне не подходит.

Есть ли простое однострочное решение для использования этого?

Ответы [ 4 ]

86 голосов
/ 04 августа 2010

Я не уверен, что то, что вы пробовали, доставляет вам неприятности, но вы можете просто передать лямбду в качестве первого аргумента Assert.Throws. Вот один из моих тестов, который проходит:

Assert.Throws<ArgumentException>(() => pointStore.Store(new[] { firstPoint }));

Хорошо, этот пример мог быть немного многословным. Предположим, у меня был тест

[Test]
[ExpectedException("System.NullReferenceException")]
public void TestFoo()
{
    MyObject o = null;
    o.Foo();
}

, который обычно проходит, потому что o.Foo() вызовет исключение нулевой ссылки.

Затем вы удалили бы атрибут ExpectedException и поместили бы ваш вызов на o.Foo() в Assert.Throws.

[Test]
public void TestFoo()
{
    MyObject o = null;
    Assert.Throws<NullReferenceException>(() => o.Foo());
}

Assert.Throws "пытается вызвать фрагмент кода, представленный как делегат, чтобы убедиться, что он выдает конкретное исключение." Синтаксис () => DoSomething() представляет собой lambda , по сути, анонимный метод. Поэтому в этом случае мы говорим Assert.Throws выполнить фрагмент o.Foo().

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

10 голосов
/ 04 августа 2010

Вот простой пример использования обоих способов.

string test = null;
Assert.Throws( typeof( NullReferenceException ), () => test.Substring( 0, 4 ) );
Assert.Throws<NullReferenceException>( () => test.Substring( 0, 4 ) );

Если вы не хотите использовать лямбды.

[Test]
public void Test()
{
    Assert.Throws<NullReferenceException>( _TestBody );
}

private void _TestBody()
{
    string test = null;
    test.Substring( 0, 4 );
}
2 голосов
/ 02 июня 2011

По умолчанию TeamCity использует NUnit 2.2.10, у которого нет ExpectedException.Обратитесь к документации TeamCity "NUnit for NAnt", чтобы узнать, как изменить ее на что-то более современное, включая конкретный список выпусков, которые предоставляет TeamCity.

0 голосов
/ 07 июня 2019

NUnit добавил новый метод Record.Exception.

Если вы предпочитаете разделять акты и утверждения, тогда

Act:

ex = Record.Exception(()={throw new Exceprtion()} 

Assert:

Assert.NotNull(ex);
...