检查异步事件是否仅引发一次

时间:2012-09-12 11:38:00

标签: c# events nunit

当我编写一个需要检查异步事件的单元测试时,我通常会这样做:

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

但是,在我目前的情况下,事件是基于与外部系统不同的事件引发的,我刚刚发现我实际上得到了重复事件,这并不好。我无法更改此其他系统,因此我需要过滤掉我班级中的重复事件。幸运的是,有一种简单的方法可以检查它是否重复,但现在我想知道如何更改单元测试以确保我的过滤工作正常。

你如何编写一个单元测试,检查一下某个动作被采取后,某个事件只被提出一次?

2 个答案:

答案 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);
}