Вопрос

Прежде чем начать, я хочу прояснить, что я уже проверил решения в обоих этот вопрос а также этот вопрос.

Метод для проверки

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, помогающим подтвердить имена), и это может быть действительно полезно, если это когда -либо вызовет в производстве Анкет (Есть некоторые громоздкие хаки, чтобы проверить аргументы другими способами, но я подозреваю, что вы не хотите видеть их ...)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top