我为调用我的 SQL Server 的 .net 代码编写了一些测试。看来 usingSystem.Transactions
是回滚对数据库所做的任何修改的绝佳选择。我知道一些纯粹主义者会建议我可能想模拟数据库,但我不会走那条路;这不是严格意义上的纯单元测试。
当我编写并运行几个测试时,这完全符合预期。我只是将用于初始化和中止 .net 事务的代码放在测试设置和测试拆卸方法中。这似乎是一个很好的解决方案。
但是,我遇到的问题是,当我尝试运行 100 个这样的测试时,它们中的许多会抛出异常,即使它们在一个接一个运行时通过,它们也无法连接到 SQL Server。更糟糕的是,当我运行测试时,我的数据库中的表有时会偶尔被锁定。我必须让我的 DBA 手动移除锁。
许多人都知道,在针对 SQL 服务器的开发工作站上运行的代码(如运行此测试)上使用 TransactionScope 将使 .net 框架使用 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
如您所见,这里没有什么特别花哨的。我只有一个测试方法,它将向我的数据库写入一些我希望我的方法找到的东西。这只是一个例子;还有很多其他类似的测试。
我的测试逻辑似乎是合理的。什么可能导致我的测试不仅失败,而且偶尔将用户锁定在表之外?