Я написал несколько тестов для кода .net, который вызывает вызовы к моему SQL Server. Похоже, что использование System.Transactions
является отличным выбором для отката любых изменений в базе данных, которые в результате. Я знаю, что некоторые пуристы предложат мне издеваться над базой данных, но я не иду по этому пути; это не совсем чистый юнит-тест.
Когда я пишу и запускаю несколько тестов, это работает точно так, как ожидалось. Я просто помещаю код для инициализации и прерывания транзакций .net в настройках теста и тестируемом методе разборки. Это казалось отличным решением.
Однако проблема, с которой я столкнулся, заключается в том, что при попытке запустить 100 из этих тестов многие из них выдают исключение, что они не могут подключиться к SQL Server, даже если они проходят при запуске по одному. Что еще хуже, таблицы в моей базе данных время от времени блокируются, когда я запускаю свои тесты. Я должен попросить моего администратора базы данных вручную снять блокировки.
Как многие из вас знают, использование TransactionScope в коде, который выполняется на рабочей станции разработки (как при выполнении этого теста) на сервере SQL, заставит .net framework использовать MSDTC.
Вот пример кода для иллюстрации того, что я делаю:
<TestInitialize()> Public Sub MyTestInitialize()
_scope = New System.Transactions.TransactionScope( _
System.Transactions.TransactionScopeOption.Required, New TimeSpan(0, 2, 0))
End Sub
<TestCleanup()> Public Sub MyTestCleanup()
_scope.Dispose()
End Sub
<TestMethod()> Public Sub CurrentProgramUser_Get_UserID()
Dim ProgramSessionId As String
Dim CurrentProgramUserId As Integer
Dim dSession As ProgramSession
CurrentDCMAUserId = Convert.ToInt32( _
SqlHelper.ExecuteScalar(testDcmaConnString, System.Data.CommandType.Text, _
"INSERT into Program_Users(UserName,FirstName,LastName) " & _
"VALUES('GuitarPlayer','Bob','Marley')" & _
"SELECT IDENT_CURRENT('Program_users') ") _
)
ProgramSessionId = session.getCurrentSession()
session.WriteUserParam("Program", ProgramSessionId, "USERID", CurrentProgramUserId.ToString(), testSource, testConnString)
Dim readValue As Integer
readValue = session.User.UserID
Assert.AreEqual(CurrentProgramUserId, readValue)
End Sub
Как видите, здесь нет ничего особенного. У меня просто есть тестовый метод, который собирается записать некоторые вещи в мою базу данных, которые я хочу, чтобы мой метод нашел. Это только один пример; Есть много других тестов, подобных этому.
Логика моих тестов, похоже, правильная. Что может быть причиной того, что мои тесты не только не срабатывают, но и время от времени блокируют пользователей из таблиц?