您好我在使用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
太慢了。测试失败了。我认为它太慢了,因为当我在Thread.Sleep
和InjectValue
之间添加Assert
来工作时。
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();
}
}
}
答案 0 :(得分:0)
我认为这是异步调用的问题。每当你在NUnit测试中有一个异步方法时,它就不会等待它完成,因为没有人真正等待它完成并返回结果。相反,您必须对异步方法执行.Wait以强制测试等待它完成。
我没有在代码编辑器中编写这段代码,所以它可能不完美,但这是基本的想法。
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 async void InjectValue(int a, int b)
{
if (CurrentBar.Inject(a,b))
{
AutoReset.WaitOne();
}
}
}
然后在你在ACT的测试方法中你做了一个.Wait
[Test]
public void FooOnValueInjectedTest()
{
// Arrange
bool OnValueInjectedWasRasied = false;
IFoo foo = new Foo();
foo.OnValueInjected += (s, e) => OnValueInjectedWasRasied = true;
// Act
foo.InjectValue(0,0).Wait();
// Assert
Assert.AreEqual(true, OnValueInjectedWasRasied);
}