【发布时间】:2015-06-05 08:38:49
【问题描述】:
由于一些限制,我不能使用实体框架,因此需要手动使用 SQL 连接、命令和事务。
在为调用这些数据层操作的方法编写单元测试时,我偶然发现了一些问题。
对于单元测试,我需要在事务中执行它们,因为大多数操作都按其性质更改数据,因此在事务之外执行它们是有问题的,因为这会更改整个基础数据.因此我需要围绕这些设置一个事务(最后没有提交)。
现在我有 2 种不同的变体来说明这些 BL 方法的工作原理。 一些内部有事务本身,而另一些则根本没有事务。这两种变体都会导致问题。
Layered Transaction:这里我收到错误消息,DTC 由于超时而取消了分布式事务(尽管超时设置为 15 分钟并且它只运行了 2 分钟)。
Only 1 Transaction:当我来到被调用方法中的
"new SQLCommand"行时,我得到一个关于Transaction 状态的错误。
我的问题是我可以做些什么来纠正这个问题并在手动正常和分层事务工作的情况下进行单元测试?
单元测试方法示例:
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction())
{
MyBLMethod();
}
}
使用方法的交易示例(非常简单)
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
connection.Open();
using (SqlTransaction transaction = connection.BeginTransaction())
{
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.Transaction = transaction;
command.CommandTimeout = 900; // Wait 15 minutes before a timeout
command.CommandText = "INSERT ......";
command.ExecuteNonQuery();
// Following commands
....
Transaction.Commit();
}
}
使用方法的非交易示例
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
connection.Open();
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandTimeout = 900; // Wait 15 minutes before a timeout
command.CommandText = "INSERT ......";
command.ExecuteNonQuery();
}
【问题讨论】:
-
由于必须使用
SqlConnection,所以不能进行单元测试;你正在做集成测试。因此,除了提交之外,不要做任何事情,而是使用一个测试数据库(您可以在测试运行开始时重新构建它)并只测试数据库交互。 -
他说了什么。您应该每次都使用数据库快照创建干净的数据库和已知数据。
-
这意味着我需要为每个单元测试运行重新创建一个完整的(可能跨越相当多 GB 的数据)数据库? b(这可能会使运行时间增加一倍或三倍,然后持续几分钟)
标签: c# sql unit-testing transactions