在C#中测试事件驱动的代码时,我想确保我的断言不会执行,直到被测对象有机会处理事件为止。目前,我正在使用AutoResetEvent
对象暂停执行,直到事件被触发为止:
private MyClassDependency testObjectDependency = new MyClassDependency();
private MyClass testObject = new MyClass(testObjectDependency);
private AutoResetEvent eventLock = new AutoResetEvent(false);
void handle(object sender, EventArgs e)
{
eventLock.Set();
}
[Test()]
public void DoSomethingTest()
{
testObjectDependency.Event += handle;
testObject.DoSomething();
eventLock.WaitOne();
testObjectDependency.Event -= handle;
testObject.IsSomethingDone.Should().Be.True();
}
在运行调试器时,我在测试事件处理程序和testObject
的事件处理程序中设置了断点,我可以看到测试处理程序首先触发,然后是处理程序I' m尝试测试开始,然后在真正的处理程序完成之前测试失败。
我应该如何更改此设置,以便在调用所有其他处理程序之后才会调用我的测试中的处理程序?我使用的是Visual Studio 2013, .NET 4.0 Client ,NUnit 2.6.3和Should.Fluent 1.0。
这个问题有点类似于this previous one,除了在这里我想保证所有其他事件处理程序都先完成。
感谢一些有用的评论,我回到我的代码并意识到问题出在我的测试设置中。这是我原来的设置代码:
[SetUp]
public void SetupDeviceController()
{
dev = new TestDevice();
dc = new DeviceController(dev);
dev.Read += dev_Read;
dc.Open();
}
dev.Read -= dev_Read;
方法中会显示匹配的[TearDown]
。
答案 0 :(得分:1)
好的,所以,当我在上面发布我的示例代码时,我正在掩饰问题的真正根源。在我的实际测试代码中,我有一个SetUp
方法实例化一个模拟依赖项对象,然后将模拟对象注入为测试中的真实对象的依赖项。然后,我在调用添加真实处理程序的真实对象方法之前,将我的测试处理程序添加到模拟对象中。这是我真正的设置代码:
[SetUp]
public void SetupDeviceController()
{
dev = new TestDevice();
dc = new DeviceController(dev);
dev.Read += dev_Read;
dc.Open();
}
我把它改为:
[SetUp]
public void SetupDeviceController()
{
dev = new TestDevice();
dc = new DeviceController(dev);
dc.Open();
dev.Read += dev_Read;
}
现在处理程序按预期顺序运行。