当我编写一个需要检查异步事件的单元测试时,我通常会这样做:
[Test]
public void test()
{
var eventRaised = new ManualResetEvent(false);
subject.SomeEvent += (s, e) => { eventRaised.Set(); };
// Do something which should have triggered the event
Assert.True(eventRaised.WaitOne(5000), "Event was not raised.");
}
但是,在我目前的情况下,事件是基于与外部系统不同的事件引发的,我刚刚发现我实际上得到了重复事件,这并不好。我无法更改此其他系统,因此我需要过滤掉我班级中的重复事件。幸运的是,有一种简单的方法可以检查它是否重复,但现在我想知道如何更改单元测试以确保我的过滤工作正常。
你如何编写一个单元测试,检查一下某个动作被采取后,某个事件只被提出一次?
答案 0 :(得分:2)
向单元测试添加计数器,并在触发事件处理程序时随时递增计数器。确保测试完成后,计数器值等于1.
[Test]
public void test()
{
int numEventsRaised = 0;
subject.SomeEvent += (s, e) => { numEventsRaised++; };
// Do something which should have triggered the event
//As per the OP's example, we will wait 5 seconds to ensure
//the async event has time to be raised.
Thread.Sleep(5000);
Assert.False((numEventsRaised == 0), "Event was not raised.");
Assert.False((numEventsRaised > 1), "Event was raised more than once.");
}
答案 1 :(得分:1)
好。由于延迟必须到期,因此单元测试需要时间(因此您确定最终会发布第二次发布)。
使用计数器并尝试减少超时。 5秒似乎有点长(这取决于外部系统)
[Test]
public void test()
{
var eventRaised = new ManualResetEvent(false);
var counter = 0;
subject.SomeEvent += (s, e) => { if (++counter) >= 2 eventRaised.Set(); };
// Do something which should have triggered the event
// you might want to decrease the timeout
Assert.False(eventRaised.WaitOne(5000), "Event was not raised.");
Assert.AreEqual(1, counter);
}