3

非同期イベントが発生する必要があることを確認する必要がある単体テストを作成するときは、通常、次のようにします。

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

ただし、私の現在のケースでは、イベントは外部システムからの別のイベントに基づいて発生し、実際には重複したイベントを取得していることに気付きました。これは良くありません。この他のシステムを変更することはできないため、クラス内の重複するイベントを除外する必要があります。幸いなことに、重複しているかどうかを確認する簡単な方法がありますが、フィルタリングが正しく機能していることを確認するには、単体テストをどのように変更すればよいか疑問に思っています。

特定のアクションが実行された後、特定のイベントが 1 回だけ発生することを確認する単体テストをどのように記述しますか?

4

2 に答える 2

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.");
}
于 2012-09-12T12:22:24.587 に答える
1

良い。遅延が期限切れになる必要があるため、その単体テストには時間がかかります (最終的な 2 番目の発行が確実にキャッチされるようにするため)。

カウンターを使用して、タイムアウトを減らしてみてください。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);
}
于 2012-09-12T12:30:27.637 に答える