NUnit: Почему не Assert.Throws Catch My ArgumentNullException?

Я отправляю этот вопрос заново по просьбе уважаемого мистера Джона Скита, который предложил мне разработать простую тестовую программу, которая изолирует и демонстрирует проблему, с которой я сталкиваюсь, и повторно публикует вопрос. Этот вопрос вырос из этого , поэтому, пожалуйста, простите меня, если все это звучит очень знакомо. Вы потенциально можете почерпнуть дополнительные сведения об этом вопросе из этого.

Проблема, с которой я сталкиваюсь, касается Assert.Throws из NUnit 2.5.9. Иногда он не сможет перехватить любые исключения, выданные в методе, вызванном TestDelegate. Я зафиксировал это поведение воспроизводимым образом в приведенном ниже коде. (Хотя, по общему признанию, это может быть случай Fails On My Machine ™.

Чтобы воспроизвести ошибку, я создал решение с двумя проектами C # DLL:

  • Первый содержит один класс с одним общедоступным Этот метод является методом расширения, который инкапсулирует логику, необходимую для создания SqlCommand , заполните его параметры и вызовите для него ExecuteScalar . Этот проект не содержит других ссылок.
  • Второй содержит единственный класс с двумя методами, которые проверяют, работает ли метод в первой DLL должным образом. Этот проект ссылается на первый и включает ссылку на NUnit Framework. Никакие другие сборки не упоминаются.

Проходя тесты в отладчике, я наблюдаю следующее:

  1. Assert.Throws правильно вызывает метод расширения ExecuteScalar .
  2. Значения параметров равны нулю, как и ожидалось.
  3. ExecuteScalar проверяет свои параметры на наличие нулевых значений.
  4. Отладчик обнаруживает и выполняет строку, содержащую throw new ArgumentNullException (.. .) .
  5. После выполнения выброса управление приложением не передается немедленно Assert.Throws . Вместо этого он продолжается на следующей строке в ExecuteScalar .
  6. Как только выполняется следующая строка кода, отладчик прерывается и отображает ошибку «Исключение нулевого аргумента не было обработано кодом пользователя. . "

Исходный код, изолирующий это поведение, приведен ниже.

МЕТОД РАСШИРЕНИЯ

namespace NUnit_Anomaly
{
    using System;
    using System.Data;
    using System.Data.SqlClient;

    public static class Class1
    {
        public static T ExecuteScalar(this SqlConnection connection, string sql)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            if (sql == null)
            {
                throw new ArgumentNullException("sql");
            }

            using (var command = connection.CreateCommand())
            {
                command.CommandType = CommandType.Text;
                command.CommandText = sql;
                return (T)command.ExecuteScalar();
            }
        }
    }
}

ТЕСТОВЫЕ СЛУЧАИ

namespace NUnit_Tests
{
    using System;
    using System.Data.SqlClient;
    using System.Diagnostics;

    using NUnit.Framework;

    using NUnit_Anomaly;

    [TestFixture]
    public class NUnitAnomalyTest
    {

        [Test]
        public void ExecuteDataSetThrowsForNullConnection()
        {
            Assert.Throws(() => ((SqlConnection)null).ExecuteScalar(null));
        }

        [Test]
        public void ExecuteDataSetThrowsForNullSql()
        {

            const string server = "MY-LOCAL-SQL-SERVER";
            const string instance = "staging";
            string connectionString = String.Format("Data Source={0};Initial Catalog={1};Integrated Security=True;",
                                                    server,
                                                    instance);

            using (var connection = new SqlConnection(connectionString))
            {
                Assert.Throws(() => connection.ExecuteScalar(null));
            }
        }
    }
}

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

ОБНОВЛЕНИЕ

Я последовал совету Ханса и проверил диалоговое окно «Исключения». Я не нарушал выброшенных исключений, но я ломал необработанные пользовательские исключения . Видимо, поэтому отладчик взламывает IDE при возникновении исключения. Снятие флажка устранило проблему, и Assert.Throws подхватил ее. Однако, если я этого не сделал, я не могу просто нажать F5, чтобы продолжить выполнение, иначе исключение станет NullReferenceException .

Итак, теперь вопрос: могу ли я настроить прерывания исключений для каждого проекта? Я хочу делать это только во время тестирования, но не в целом.

15
задан Community 23 May 2017 в 12:24
поделиться