【发布时间】:2010-03-10 22:14:06
【问题描述】:
基本问题是如何创建需要调用方法的单元测试,等待被测类上发生事件,然后调用另一种方法(我们实际要测试的方法)?
如果您有时间进一步阅读,以下是场景:
我正在开发一个必须控制硬件的应用程序。为了避免依赖硬件可用性,当我创建我的对象时,我指定我们在测试模式下运行。发生这种情况时,正在测试的类会创建适当的驱动程序层次结构(在本例中是硬件驱动程序的薄模拟层)。
假设有问题的类是电梯,我想测试给出电梯楼层号的方法。这是我的虚拟测试现在的样子:
[TestMethod]
public void TestGetCurrentFloor()
{
var elevator = new Elevator(Elevator.Environment.Offline);
elevator.ElevatorArrivedOnFloor += TestElevatorArrived;
elevator.GoToFloor(5);
//Here's where I'm getting lost... I could block
//until TestElevatorArrived gives me a signal, but
//I'm not sure it's the best way
int floor = elevator.GetCurrentFloor();
Assert.AreEqual(floor, 5);
}
编辑:
感谢您的所有回答。这就是我最终实现它的方式:
[TestMethod]
public void TestGetCurrentFloor()
{
var elevator = new Elevator(Elevator.Environment.Offline);
elevator.ElevatorArrivedOnFloor += (s, e) => { Monitor.Pulse(this); };
lock (this)
{
elevator.GoToFloor(5);
if (!Monitor.Wait(this, Timeout))
Assert.Fail("Elevator did not reach destination in time");
int floor = elevator.GetCurrentFloor();
Assert.AreEqual(floor, 5);
}
}
【问题讨论】:
-
在目标操作系统上调用是否会被阻塞?
-
没有。一旦你调用 .GoToFloor(floor) 它就会返回,但是电梯将状态更改为“正在移动”,需要一段时间才能到达该楼层,然后它会引发一个事件(可能在不同的线程中)
-
嗨,这应该可以解决我测试异步操作的问题。我使用上面的代码作为起点,但是 Monitor.Pulse 不会导致 Wait 重新获取锁,它会超时导致 Assert.Fail("Event did notarrive") 触发。任何想法为什么这可能是......!?
-
以上编辑中的解决方案在 Monitor.Pulse 周围缺少
lock。
标签: c# events asynchronous tdd