Sim オブジェクトの状態に応じてイベントを発生させるアプリケーションがあります。特に、Sim の状態が変化した場合 (つまり、PinRequired から Accessible に変化した場合)、OnStatus イベントが発生します。イベントは、新しいスレッドでリスナーに通知します。
私は単体テストで Moq を使用しており、OnStatus が次のように発生していると主張できます。
[Test]
public void TestOnStatusIsRaised()
{
Sim sim = new Sim();
sim.OnStatus += OnStatus;
lock (this)
{
sim.UpdateSimInfo(new Info("a new status"));
Monitor.Wait(this);
}
Assert.IsTrue(_onStatusCalled);
}
private void OnStatus(SimStatus obj)
{
lock (this)
{
_onStatusCalled = true;
Monitor.Pulse(this);
}
}
ご覧のとおり、Monitor クラスを使用すると、イベントが発生するまで待ってから、処理を進めて _onStatusCalled フラグが true に設定されていることをアサートできます。
イベントが発生していないことを主張したいときに問題が発生します。テストが永遠に待機するため、モニターを使用してイベントが発生しないのを待つことはできません! 待機にタイムアウトを追加することもできましたが、それは汚いハックのようです。
私は次のことを試しました:
[Test]
public void TestOnStatusIsNotFired()
{
Sim sim = new Sim();
sim.OnStatus += onStatus => Assert.Fail("OnStatus Was called");
sim.UpdateSimInfo(new Info("the same status"));
}
しかし、それは機能しません。イベントが発生しないようにコードを修正する前に、テストは常にパスします。コードをステップ実行して、 によってスローされる例外を確認しましたAssert.Fail()
が、イベントが try/catch ブロックで発生し、NUnit 例外がキャッチされるため、テストが失敗することはありません。
何か案は?