在这个asp.net中,我正在清理它可能会发生死锁。我想确保代码正确处理它们,所以我正在尝试编写触发死锁的NUnit测试.....
DAO按实体分割。每个实体都有一组测试,这些测试由Startup()和Teardown()方法包围,这些方法创建一个transactioncope,然后在测试完成后将其回滚。这对其他一切都很有用,但对死锁完全没用。
如何使用可以可靠地再现的TransactionScope和SQL2000(即涉及MSDTC)来设置和运行“死锁”测试? 更多细节:我知道如果两个用户使用不同的,特定的数据值调用两个函数,则会出现死锁 的结果。如何在NUNIT中模拟这个 - 并使死锁始终?
是的,我确实从“为什么不首先停止发生的死锁”行动计划开始,但我无法控制可能发生死锁的代码 - 我只是调用函数和他们可以陷入僵局。
答案 0 :(得分:2)
如果您的死锁导致抛出异常,您希望使用Mock对象来模拟抛出的异常。
基本的想法是你告诉你的Mock对象框架(我喜欢TypeMock)而不是抛出异常,如下所示:
MockObject mo = MockManager.MockObject(typeof(MyDeadlockException));
mock.ExpectAndThrow("MyMethod", (MyDeadlockException)mo.Object);
其他模拟框架的想法基本相同。
答案 1 :(得分:1)
答案 2 :(得分:0)
如果您在交易过程中的某个测试只是“等待”5分钟,该怎么办?或者,您只需编写一个启动事务的测试,创建一个新记录,然后在不提交的情况下更新该记录。然后,启动新事务并尝试读取已创建且当前正在更新的记录。你会在那里遇到僵局。
答案 3 :(得分:0)
如果您手动锁定表并始终将其锁定,该怎么办?那么,你对该表采取的任何行动都会产生死锁情况?
答案 4 :(得分:0)
来到这个盲区,但是你可以在你的TestSetup方法中实际创建一个SQLConnection到你的数据库吗?然后,使用它,您可以发出一个命令来锁定表或采取一些操作来锁定记录或页面?这样,它会超出您正在进行的任何其他交易吗?看起来这可能是你已经考虑过的一个选择。我对你的情况有什么看法?
答案 5 :(得分:0)
对于单元测试,您可能希望避免实际使用数据库。你怎么知道你有僵局您应该测试条件,告诉您存在死锁并在测试中创建死锁。
如果你调用一个服务并且它返回一个错误,模拟是一个理想的模仿。只需让模拟返回您期望的错误。如果您正在等待超时或其他什么,那么同样适用。
通常,单元测试应仅在正在测试的代码上运行,而不是依赖于任何其他代码或组件。也就是说 - 数据库本质上是另一个组件,您可能正在使用nunit进行某种功能测试来驱动它们。
在这种情况下,你真的必须创建一个死锁情况,但是锁定一个记录或表,然后调用一个试图使用相同记录并处理响应的组件。