2009-04-15 15 views
2

このテストは、NUnitコンソールランナーを使用して実行すると失敗します。私はTestDriven.NETとちょうどそのテストを実行する場合、それは動作しますが、私はTestDriven.NETとスイート全体実行する場合ではない:C#/。NET NUnitを使用したBackgroundWorkerのテスト

[Test] 
public void BackgroundWorkerFiresRunWorkerCompleted() 
{ 
    var runner = new BackgroundWorker(); 
    ManualResetEvent done = new ManualResetEvent(false); 
    runner.RunWorkerCompleted += delegate { done.Set(); }; 

    runner.RunWorkerAsync(); 

    bool res = done.WaitOne(TimeSpan.FromSeconds(10)); 
    // This assert fails: 
    Assert.IsTrue(res, "RunWorkerCompleted was not executed within 10 seconds"); 
} 

を私は問題があると思われるメッセージループを持っていないとは何かを持っているが、私はわかりません。

BackgroundWorkerを使用するための要件は何ですか?

テストを行うための回避策はありますか?

答えて

7

私はそれがメッセージポンプと関係しているとは思えません。なぜなら、テストは通常​​、とにかくブロッキングの形で実行されるからです。しかし、イベントが処理されないウィンドウメッセージを使用する「UI」スレッドで呼び出されることがあります。

だから、問題が処理されていないメッセージポンプやウィンドウのメッセージだった場合、あなたはあなたの現在のbool res = done.WaitOne(TimeSpan.FromSeconds(10));行を置き換えるために、次のように試みることができる:

DateTime end = DateTime.Now.AddSeconds(10); 
bool res = false; 
while ((!res) && (DateTime.Now<end)) { 
    Application.DoEvents(); 
    res = done.WaitOne(0): 
} 
+0

それは動作します。ありがとう! –

+0

DoEvents()は、テスト(または同じテストの前のテスト)がWindowsのフォームまたはコントロールをインスタンス化する場合にのみ必要です。どうして? –

+0

どのWinFormsコントロールでも、ウィンドウメッセージはメッセージポンプを通過する必要があります。DoEvents()を呼び出さないと発生しません。 – Lucero

0

BGW DoWorkイベントハンドラがありませんか?

+0

実際のクラスは、BackgroundWorkerというサブクラスをテストし、OnDoWork()をオーバーライドします。しかし、DoWorkイベントハンドラを追加しても違いはありません。 RunWorkerCompletedイベントハンドラはまだ実行されていません。 –

-2

ちょうどあなたの前にスリープを追加します。

このようなAssert.IsTrue(res, "RunWorkerCompleted was not executed within 10 seconds");

何か:

System.Threading.Thread.Sleep(10000);

+3

しかしそれは、テストが常に10秒以上かかることを意味します。通常は、ミリ秒単位で終了する必要があります。 –

関連する問題