NUNIT, не утверждают.
Вопрос
Прежде чем начать, я хочу прояснить, что я уже проверил решения в обоих этот вопрос а также этот вопрос.
Метод для проверки
public static DataSet ExecuteDataSet(this SqlConnection connection, string sql)
{
if (null == connection || null == sql)
{
throw new ArgumentNullException();
}
using (var command = connection.CreateCommand())
{
// Code elided for brevity
}
}
Методы испытаний
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ExecuteDataSetThrowsForNullConnection()
{
((SqlConnection)null).ExecuteDataSet("SELECT TOP 1 * FROM prep");
}
[Test]
public void ExecuteDataSetThrowsForNullSql()
{
Assert.Throws<ArgumentNullException>(
() => Resource.Connection.ExecuteDataSet(null)
);
}
Странное поведение
Ни одна версия тест Метод улавливает ArgumentNullException
что бросается сразу после входа в ExecuteDataSet
метод Поток управления переходит к следующей строке (using (var command = connection.CreateCommand())
) и NullReferenceException
Вместо этого происходит (что, конечно, не обрабатывается ни одним из моих тестовых случаев, потому что это никогда не должно быть брошено).
Первоначально первый метод испытаний (ExecuteDataSetThrowsForNullConnection
) выглядел так же, как второй (ExecuteDataSetThrowsForNullSql
) Когда Assert.Throws
не удалось поймать исключение, я провел некоторое исследование и отметил, что некоторые люди рекомендовали использовать ExpectedException
вместо. Я изменил тестовый код соответственно, но безрезультатно.
Для записи это 32-битный код .NET 3.5, протестированный в NUNIT 2.5.9. Я использую TestDriven.net для интеграции Visual Studio и установил последние версии NCOVER и NDEPEND.
TL; DR Вопрос
Почему методы испытаний не поймают исключение, которое брошено, и как это исправить?
РЕДАКТИРОВАТЬ
Эта версия метода тестирования работает.
[Test]
public void ExecuteDataSetThrowsForNullConnection()
{
try
{
((SqlConnection)null).ExecuteDataSet("SELECT TOP 1 * FROM prep");
}
catch(ArgumentNullException e)
{
Assert.AreEqual(true, true);
}
catch (Exception e)
{
Assert.Fail("Expected ArgumentNullException, but {1} was thrown instead.", e.GetType().Name);
}
}
Решение
Я предполагаю, что вы на самом деле не тестируете код, который вы думаете. Попробуйте положить немного Console.WriteLine
Заявления и посмотрите, напечатаны ли они. Если вы положите точку останова на throw
заявление и запустить тесты в отладчике, получает ли удар по перерывам? Если контроль переходит к следующему утверждению, это означает, что исключение никогда не будет выброшено - оно не может быть пойман таким образом, что позволит выполнить продолжиться в методе броска, если только вы не нашли В самом деле странная ошибка CLR.
Я написал много такого кода, и он никогда не потерпел неудачу в NUNIT.
Кроме того, я рассматриваю это как хорошую практику, чтобы включить имя параметра в аргументы, поэтому я бы написал:
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (sql == null)
{
throw new ArgumentNullException("sql");
}
У этого есть печальная проблема, связанная с тем, чтобы быть длинным и повторять имена параметров в коде как строки ... но достаточно легко получить правильно (особенно с Resharper, помогающим подтвердить имена), и это может быть действительно полезно, если это когда -либо вызовет в производстве Анкет (Есть некоторые громоздкие хаки, чтобы проверить аргументы другими способами, но я подозреваю, что вы не хотите видеть их ...)