我在Visual Studio 2008中调试单元测试时遇到问题。单元测试使用System.Timers.Timer
(在业务逻辑中)来处理某个延迟(1'000毫秒)。运行测试的线程将进入休眠状态5,000小时。
当自己运行测试时,它会通过。当运行所有测试(> 120)时,它有时会通过,有时会失败(不确定)。然后我尝试在模拟对象中设置断点,在那里我设置在单元测试中断言的标志。现在,当我自己调试测试时,我得到了Assert.IsTrue()
失败的现象,但Quick Watch告诉我,这是真的:
public class ObjectManagerAccessMock : IObjectManagerAccess
{
public bool ExecuteCommandWasCalled { get; set; }
public void ExecuteCommand()
{
ExecuteCommandWasCalled = true; //set breakpoint here
}
}
当另一个线程停止时(通过断点),运行测试的线程是否继续运行?
答案 0 :(得分:1)
我怀疑你在调试时看到的是副作用。断言失败,因为它是错误的,但由于线程问题,当您在调试器中查看它时,该值为true。
增加测试中的超时应解决问题,但要小心。
一开始计时器似乎是一个好主意,但它们可能会在以后导致问题。环境问题,例如其他执行进程或在较慢的机器上运行测试,将推动计时器的使用方式。不幸的是,如果你将超时增加到满足最慢机器的需要,你最终会得到一系列非常慢的测试。
不要在测试中使用Thread.Sleep,而应考虑寻找使测试运行速度与代码一样快的方法。例如,在操作完成后,在测试主题上引发事件。
[Test]
public void DemonstrateThatTheTestRunsAsFastAsTheSubjectUnderTest()
{
var resetEvent = new ManualResetEvent(true);
// configure our test to listen for the completed event
var subject = new MyTestSubject();
subject.OnComplete += (sender,e) => resetEvent.Set();
// perform the long running asynchronous operation
subject.DoLongRunningOperation();
// wait up to 10 seconds
resetEvent.WaitOne(100000);
Assert.AreTrue(subject.OperationComplete);
}
在上面,我们使用 ManualResetEvent ,它将阻止执行,直到调用 Set 操作。另请注意,我正在为重置事件提供超时值,以便操作不会永远运行。如果超时超时,我们的 OperationComplete 可能仍为false,因此测试失败。
如果您想要更精细的细节来确定测试是否超时, WaitOne 方法会返回一个布尔值,指示操作是否成功。
bool completedWithoutTimeout = resetEvent.WaitOne(10000);
Assert.IsTrue(completedWithoutTimeout, "The operation timed out.");
答案 1 :(得分:0)
有时候你的BL占用时间超过4秒,因此加起来超过5秒并且断言失败,但是当你能够通过Quick Watch操作检查它时,操作完成并且调用将值设置为true。 / p>
我非常肯定1)断言失败原因值在断言时为假2)当你检查时值为真,并且这两个动作之间的时间> 0