Можно ли выполнить откат зафиксированных данных с помощью TransactionScope? - PullRequest
5 голосов
/ 21 ноября 2011

Цель проста - данные отката, вставленные в модульном тесте. Вот как это происходит. В модульном тесте вызывается метод, который создает новое соединение и вставляет некоторые данные. После этого модульный тест создает новое соединение и пытается найти то, что было вставлено, и подтвердить это. Я надеялся обернуть эти две вещи с помощью TransactionScope, а не вызвать Complete и увидеть, что вставленные данные откатились. Этого не происходит Я что-то не так делаю, или я просто упускаю суть?

using (new TransactionScope())
{
    // call a method that inserts data
    var target = new ....
    target.DoStuffAndEndupWithDataInDb();

    // Now assert what has been added.
    using (var conn = new SqlConnection(connectionString))
    using (var cmd = conn.CreateCommand())
    {
        // Just read the data from DB
        cmd.CommandText = "SELECT...";
        conn.Open();
        int count = 0;
        using (var rdr = cmd.ExecuteReader())
        {
            // Read records here
            ...
            count++;
        }

        // Expecting, say, 3 records here
        Assert.AreEqual(3, count);
    }
}

РЕДАКТИРОВАТЬ: Я не думаю, что на моей машине был запущен и настроен DTC. Поэтому я запустил службу и попытался настроить DTC, но я получаю эту ошибку. enter image description here

Ответы [ 4 ]

1 голос
/ 22 ноября 2011

вы используете MSTest?затем вы можете использовать MsTestExtensions , который вы должны получить из юнит-теста из MSTestExtensionsTestFixture, а ваш тест должен иметь TestTransaction атрибут, он использует AOP для автоматического запуска транзакции и ее отката.

1 голос
/ 21 ноября 2011

Правильно ли настроен координатор распределенных транзакций?Это большая ошибка при попытке использовать TransactionScope, как это ... если он не настроен, иногда вы получите сообщение об ошибке, но в других случаях транзакция просто фиксируется, а не откатывается.

Я бы порекомендовал взглянуть на эту статью , которая показывает все различные шаги, которые необходимо выполнить для отката ваших модульных тестов с использованием MSDTC.

1 голос
/ 21 ноября 2011

Я не думаю, что вы упускаете суть, а просто неправильно решаете проблему.

В терминах NUnit понятиями являются [SetUp] и [TearDown] методы.Вы уже определили метод настройки в своем описании, и ваш метод разрыва должен просто отменить то, что сделал метод настройки (при условии, что тестирование у вас не имеет остаточных побочных эффектов).

0 голосов
/ 22 ноября 2011

Ваш код должен работать так, как вы ожидаете.Как вы добавляете данные в DoStuffAndEndupWithDataInDb()?Мне интересно, не участвует ли инициализация данных в транзакции.

Для справки, следующее консольное приложение правильно выводит 3 rows и не фиксирует строки в базе данных (проверено с помощью SSMS).

public class Program
{
    private static void Main(string[] args)
    {
        using (var trx = new TransactionScope())
        {
            InitializeData();

            using (var connection = new SqlConnection("server=localhost;database=Test;integrated security=true"))
            using (var command = connection.CreateCommand())
            {
                command.CommandText = "select count(*) from MyTable";
                connection.Open();
                Console.WriteLine("{0} rows", command.ExecuteScalar());
            }
        }
        Console.ReadLine();
    }

    private static void InitializeData()
    {
        using (var connection = new SqlConnection("server=localhost;database=Test;integrated security=true"))
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "insert into MyTable values (1),(2),(3)";
            connection.Open();
            command.ExecuteNonQuery();
        }
    }
}
...