【发布时间】:2012-09-15 14:57:45
【问题描述】:
我有一个应用程序根据 Sim 对象的状态引发事件。特别是,如果 Sim 的状态发生变化 - 即从 PinRequired 变为 Accessible - 将引发 OnStatus 事件。事件通知新线程上的侦听器。
我在单元测试中使用 Moq 并且能够断言 OnStatus 是这样引发的:
[Test]
public void TestOnStatusIsRaised()
{
Sim sim = new Sim();
sim.OnStatus += OnStatus;
lock (this)
{
sim.UpdateSimInfo(new Info("a new status"));
Monitor.Wait(this);
}
Assert.IsTrue(_onStatusCalled);
}
private void OnStatus(SimStatus obj)
{
lock (this)
{
_onStatusCalled = true;
Monitor.Pulse(this);
}
}
如您所见,使用 Monitor 类,我可以等到引发事件后再继续并断言 _onStatusCalled 标志已设置为 true。
当我想断言没有引发事件时,我的困难就出现了。我不能使用 Monitor 等待事件不被引发,因为测试会永远等待!我可以在等待中添加一个超时,但这似乎是一个肮脏的黑客攻击。
我尝试了以下方法:
[Test]
public void TestOnStatusIsNotFired()
{
Sim sim = new Sim();
sim.OnStatus += onStatus => Assert.Fail("OnStatus Was called");
sim.UpdateSimInfo(new Info("the same status"));
}
但它不起作用 - 在修复代码以确保不引发事件之前,测试始终通过。我什至单步执行了代码并观察到Assert.Fail() 引发了异常,但这不会导致测试失败,因为我的事件在 try/catch 块中引发并且 NUnit 异常被捕获。
有什么想法吗?
【问题讨论】:
-
你不能在你想测试的代码循环完成时做一个事件,当你收到那个事件时,确保没有引发另一个事件吗?
标签: c# unit-testing events moq