是否可以使用 TransactionScope 回滚已提交的数据?
目标很简单 - 回滚单元测试插入的数据。事情是这样的。在单元测试中,调用一个方法来创建新连接并插入一些数据。之后,单元测试创建一个新连接并尝试查找已插入的内容并对其进行断言。我希望用 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,但收到此错误。
The goal is simple - rollback data inserted by a unit test. Here is how it goes. In a unit test, a method is called that creates a new connection and inserts some data. After that a unit test creates a new connection and tries to find what has been inserted and assert that. I was hoping to wrap these two things with TransactionScope
, not call Complete
and see inserted data rolled back. That's not happening. Am I doing something wrong or I am just missing the point?
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);
}
}
EDIT: I don't think I had DTC running and configured on my machine. So I started the service and tried to configure DTC but I am getting this error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你在使用 MSTest 吗?那么你可以使用 MsTestExtensions
您的单元测试需要从
MSTestExtensionsTestFixture
派生,并且您的测试需要具有TestTransaction
属性,它使用 AOP 自动启动事务并回滚。are you using MSTest ? then you can use MsTestExtensions
you unit test needs to derive from
MSTestExtensionsTestFixture
and your test needs to haveTestTransaction
Attribute, it uses AOP to automatically start a transaction and roll it back.我不认为你没有抓住重点,只是错误地解决了问题。
在 NUnit 术语中,概念是
[SetUp]
和[TearDown]
方法。您已经在描述中定义了设置方法,并且您的拆卸方法应该撤消设置方法所做的操作(假设您的单元测试没有残留副作用)。I don't think you're missing the point but just attacking the problem incorrectly.
In NUnit terms, the concepts are
[SetUp]
and[TearDown]
methods. You've already defined the setup method in your description and your tear down method should just undo what the setup method did (assuming what you're unit testing has no residual side effects).您是否正确配置了分布式事务协调器?当尝试像这样使用
TransactionScope
时,这是一个很大的问题...如果未配置它,有时您会收到错误,但其他时候事务只会提交而不回滚。我建议您查看这篇文章,它向您展示了所有内容使用 MSDTC 回滚单元测试所需执行的各个步骤。
Do you have Distributed Transaction Coordinator properly configured? This is a big gotcha when trying to use
TransactionScope
like this... if it isn't configured, sometimes you'll get an error, but other times the transaction will just commit and not rollback.I'd recommend looking at this article, which shows you all the various steps that need to be done in order to rollback your unit tests using MSDTC.
您的代码应该按您的预期工作。如何在
DoStuffAndEndupWithDataInDb()
中添加数据?我想知道数据初始化是否不参与事务。作为参考,以下控制台应用程序正确输出
3 行
,并且不会将这些行提交到数据库(使用 SSMS 检查)。Your code should work as you expect. How are you adding data in
DoStuffAndEndupWithDataInDb()
? I'm wondering whether the data initialization is not participating in the transaction.For reference, the following console application correctly outputs
3 rows
, and does not commit the rows to the database (checked using SSMS).