嗨我有一个问题,使用NUnit
测试事件。我甚至不确定这应该是单元还是功能测试。首先,让我告诉你的样品类(我想测试OnValueInjected
事件):如何在单元测试时捕捉事件?
public class Foo
{
private IBar CurrentBar { get; set; }
public event EventHandler<MoveEventArgs> OnValueInjected;
public Foo()
{
StartFoo();
}
private async void StartFoo()
{
await Task.Factory.StartNew(() =>
{
while (State != FooState.Finished)
{
IResult result = CurrentBar.WaitForValue(); // This is blocking function, wait for a value
OnValueInjected?.Invoke(this, new ResultEventArgs(result));
// .. rest of the loop
}
});
}
public void InjectValue(int a, int b)
{
CurrentBar.Inject(a,b);
}
}
所以,基本上我想要做的是订阅事件,请拨打InjectValue
和检查活动被称为。就像这样:
[Test]
public void FooOnValueInjectedTest()
{
bool OnValueInjectedWasRasied = false;
IFoo foo = new Foo();
foo.OnValueInjected += (s, e) => OnValueInjectedWasRasied = true;
foo.InjectValue(0,0);
Assert.AreEqual(true, OnValueInjectedWasRasied);
}
很简单,但它看起来像InjectValue
太慢。测试失败..我认为这太慢了,因为当我在InjectValue
和Assert
之间添加Thread.Sleep
时就起作用了。
foo.InjectValue(0,0);
Thread.Sleep(1000);
Assert.AreEqual(true, OnValueInjectedWasRasied);
有没有更好的方法来测试这样的事件?由于
我固定我的课,所以它现在是这样的:
public class Foo
{
private AutoResetEvent AutoReset { get; }
private IBar CurrentBar { get; set; }
public event EventHandler<MoveEventArgs> OnValueInjected;
public Foo()
{
AutoReset = new AutoResetEvent(false);
StartFoo();
}
private async void StartFoo()
{
await Task.Factory.StartNew(() =>
{
while (State != FooState.Finished)
{
IResult result = CurrentBar.WaitForValue(); // This is blocking function, wait for a value
OnValueInjected?.Invoke(this, new ResultEventArgs(result));
AutoReset.Set();
// .. rest of the loop
}
});
}
public void InjectValue(int a, int b)
{
if (CurrentBar.Inject(a,b))
{
AutoReset.WaitOne();
}
}
}
那么,你想* *您'InjectValue'返回的事件处理程序肯定有人提出过吗?你基本上看到了异步的自然结果......它不是关于事件,而是关于异步执行。 –
@JonSkeet嗯..从技术上讲,你是说'InjectValue'可以被阻止,直到'OnValueInjected'被提出?我没有想到这个实际上.. –
如果你想*的行为,你可以确保它,是的。不管你是否做了不同的事情。 –