最基本的问题是,我如何创建一个单元测试,它需要调用一个方法,等待一个事件发生在被测试的类上,然后调用另一个方法(我们实际上想要测试的那个方法)?
如果您有时间进一步阅读以下内容:
我正在开发一个必须控制硬件的应用程序。为了避免硬件可用性的依赖性,在创建对象时,我指定在测试模式下运行。发生这种情况时,正在测试的类将创建适当的驱动程序层次结构(在本例中是硬件驱动程序的一个瘦模拟层)。
假设所讨论的类是一个电梯,我想测试一种方法,该方法给出电梯所在的楼层号。下面是我的虚拟测试现在的样子:

[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);
        }
    }

最佳答案

我想你已经说对了。测试需要等到事件发生或者您判断到达时间太长,应该放弃等待。
要做到这一点,您可以使用monitor.wait和超时测试,并让它与monitor.pulse信号当事件到达。
[TestMethod]public void TestGetCurrentFloor(){ var elevator = new Elevator(Elevator.Environment.Offline); elevator.ElevatorArrivedOnFloor += TestElevatorArrived; lock (this) { elevator.GoToFloor(5); // NOTE: this must hand off to a second thread, and the ElevatorArrivedOnFloor must be raised by this other thread otherwise the Monitor will be pulse before we've started waiting for it if (!Monitor.Wait(this, TIMEOUT)) Assert.Fail("Event did not arrive in time."); } int floor = elevator.GetCurrentFloor(); Assert.AreEqual(floor, 5);}private void TestElevatorArrived(int floor){ lock (this) { Monitor.Pulse(this); }}
(这里的Assert.Fail()调用应该替换为单元测试工具用于显式失败测试的任何机制,否则您可能抛出异常。)

08-27 09:35