Интеграционные тесты - откат сложных транзакций - PullRequest
0 голосов
/ 19 января 2011

Для целей интеграционного тестирования мы сохраняем данные и читаем их обратно из SQL. Чтобы избежать «мусора» в тестовой базе данных, он выполняется в транзакции и откатывается.

Во время выполнения этой транзакции выдается исключение «Ошибка транзакции»:

using (var transaction = new TransactionScope()) 
{
    // saving (submitchanges)
    // reading (linq2sql select to get saved data)   // 'Transaction has aborted' was thrown

    // rollback
} 

При использовании явной обработки соединения / транзакции это работает хорошо, но код выглядит ужасно.

Что я могу сделать?

Среда : .NET 3.5 / C #, MSSQL2k8

Подробное исключение:

System.Transactions.TransactionAbortedException: транзакция прервана. ----> System.Transactions.TransactionPromotionException: ошибка при попытке продвижения транзакции. ----> System.Data.SqlClient.SqlException: уже существует открытый DataReader, связанный с этой командой, который должен быть закрыт первым. *

Ответы [ 2 ]

1 голос
/ 21 января 2011

Если вы не тестируете структуру БД, я бы посоветовал удалить БД из уравнения все вместе и перейти к подходу внедрения зависимостей. Если вы используете LINQ to SQL, а не хранимые процедуры, это означает, что вы можете фактически контролировать, откуда поступают данные, представляющие интерес, т. Е. В обычных условиях это будет база данных, а при тестировании это могут быть заранее определенные наборы объектов. Чтобы абстрагировать использование от данных, вы должны определить интерфейс / абстрактный класс поставщика данных с набором IQuariable<T> свойств. Реализация по умолчанию связывает их с таблицами базы данных, реализация теста генерирует их в памяти. Все, что вам нужно сделать сейчас, это внедрить тот или иной экземпляр реализации.

1 голос
/ 19 января 2011

Я боролся с этим вопросом в течение ряда лет.Есть в основном две крайности, которые вы должны выбрать:

  1. Загромождение вашего кода тестовой транзакцией и кодом отката, который подвержен ошибкам, и
  2. Выполнение полного сброса базы данныхмежду каждым тестом.

Заметьте, я сказал "сбросить", а не "восстановить" ... это не должно быть настолько интенсивным.Я предложил несколько подходов, в том числе отсоединение и повторное присоединение mdf-файла канонического тестирования (намного быстрее, чем восстановление, по крайней мере, тогда), выполнение сценария сброса дампа данных (усечение или удаление всех таблиц и их сброс).).

В последнее время я смотрел на Sql Сравнение RedGate ... Я до сих пор не совсем уверен, как это собрать.Но в конечном итоге я прошел весь путь транзакции / отката и решил, что в уравнение тестирования введено слишком много кода, не проверенного модулем.

...