2010-11-19 5 views
1

私のテストではがほとんどの場合に合格しますが、失敗することがあります。私はそれがスレッドの問題かもしれないと思うが、ロックや睡眠などを試して、問題がどこにあるのか見つけようとはしなかった。私は正しい構文を使用していますか?しばらくしてRhinoを使用して戻ってきました。Rhino MocksのAAA構文とスレッドの安全性

ここで私のテストのサニタイズバージョンです。私が言うように、彼らは4回のうち3回働いたが、それからブームを起こす。

[TestFixture] 
public class Tests 
{ 
    [Test] 
    public void ReprocessItems() 
    { 
     // Arrange 
     Presenter presenter = new Presenter(); 

     Model model = new Model(); 

     model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 3 }) { IsSelected = false }); 
     model.Data.Add(new ViewModel(new Item { Id = 4 }) { IsSelected = false }); 

     presenter.Model = model; 

     var gateway = MockRepository.GenerateStub<IGateway>(); 
     presenter.Gateway = gateway; 

     // Act 
     presenter.ReprocessItems(); 

     // Assert 
     gateway.AssertWasCalled(o => o.ReprocessItem(1, presenter.ReprocessDone)); 
     gateway.AssertWasCalled(o => o.ReprocessItem(2, presenter.ReprocessDone)); 
    } 

    [Test] 
    public void ShowItemReferralCommentary() 
    { 
     // Arrange 
     Presenter presenter = new Presenter(); 

     Model model = new Model(); 
     model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = false }); 

     presenter.Model = model; 

     var gateway = MockRepository.GenerateStub<IGateway>(); 
     presenter.Gateway = gateway; 

     var view = MockRepository.GenerateStub<IView>(); 
     presenter.View = view; 

     gateway.Stub(x => x.RequestItemCommentary(1)).Return("This is some commentary"); 

     // Act 
     presenter.ShowItemReferralCommentary(); 

     // Assert 
     gateway.AssertWasCalled(o => o.RequestItemCommentary(1)); 

     view.AssertWasCalled(o => o.ShowMessageBox("This is some commentary", "Referral Commentary")); 
    } 

    [Test] 
    public void AcceptSelectedItems() 
    { 
     // Arrange 
     Presenter presenter = new Presenter(); 

     Model model = new Model(); 
     model.Data.Add(new ViewModel(new Item { Id = 1 }) { IsSelected = false }); 
     model.Data.Add(new ViewModel(new Item { Id = 2 }) { IsSelected = false }); 
     model.Data.Add(new ViewModel(new Item { Id = 3 }) { IsSelected = true }); 
     model.Data.Add(new ViewModel(new Item { Id = 4 }) { IsSelected = true }); 

     presenter.Model = model; 

     var gateway = MockRepository.GenerateStub<IGateway>(); 
     presenter.Gateway = gateway; 

     // Act 
     presenter.AcceptSelectedItems(); 

     // Assert 
     gateway.AssertWasCalled(o => o.AcceptItem(3, presenter.AcceptCompleted)); 
     gateway.AssertWasCalled(o => o.AcceptItem(4, presenter.AcceptCompleted)); 
    } 
} 

編集:**以下のコメントに従って、私は一時的にThread.Sleep(500)を追加してこれを解決しました。それぞれが断言する前に。 Thread.Sleepsは一般的にコードの匂いですが、私はそれをロックしたいと思いますが、私は が駄目です。 は実用的です。あなたがより良い方法を持っているなら、私に知らせてください。

+0

これはスレッド化されたメソッドですか? – Simone

+0

ReprocessItemとReprocessDoneのようなものがコールバックです。 –

答えて

5

問題は、子スレッドが自分の仕事をしているかどうかにかかわらず、アサーションを配置したテストメソッドの最後にある可能性があるということです。あなたの視点では、ほとんどランダムです。

スレッドメソッドをテストするときにできることは、ManualResetEventなどの同期オブジェクトを使用することです。あなたのモックは、オブジェクトがテストされることによって起動されたとき、あなたはそのステータスを設定し、その後

var wait = new ManualResetEvent(false); 

を:あなたは始まった試験方法で、これをfalseにリセットし

Expect.Call(() => yourMock.yourMethod(whatever)).WhenCalled(x => wait.Set()); 

、あなたのアサーション・ブロック・コードの前に

Assert(wait.WaitOne(timeoutOfYourChoice)); 

これは、作業を完了するのに十分な時間を二次スレッドに委ねます。

+0

これを入れてみましたが、どこかに何かが壊れていました。もし私が主張する前に単純なThread.Sleep(500)を入れたら、それは動作します。理想的ではありません。私はこれを研究します。 ManualResetEventが勝者になる可能性があります。先端に感謝します。 –

関連する問題