2009-08-21 1 views
0

このシナリオのテストに問題があります。完成と未完成 - -Rhinoモックを使用してテストを実行する前に、オブジェクトを設定するために呼び出す必要があるメソッドをテストするにはどうすればよいですか?

請求書は2つの状態があり、私はこの方法Presenter.FinishInvoiceは()DAO.FinishInvoice呼び出すことをテストしたい()、その後DAO.GetInvoice()を呼び出し、その結果をView.Invoiceを設定します。問題は、DAO.GetInvoice()を呼び出す必要があることです。まず、Invoiceを完成させる必要があり、これはPresenter.InitializeView()(別のテストでテスト済み)から呼び出されます。

は、ここに私のテストです:

using (mocks.Record()) 
{ 
    SetupResult.For(view.Invoice).PropertyBehavior(); 
    SetupResult.For(DAO.GetInvoice(1)).Return(invoice); 
    Expect.Call(DAO.FinishInvoice(1)).Return(true); 
    Expect.Call(DAO.GetInvoice(1)).Return(invoice); 
} 
using (mocks.Playback()) 
{ 
    Presenter presenter = new Presenter(view, DAO); 
    presenter.InitializeView(1); 
    presenter.FinishInvoice(); 
} 

DAO.GetInvoice()が呼び出されるとInitializeView()が呼び出されたときにView.Invoiceは、一度設定しました。テストの一部ではありませんが、View.Invoiceを未処理の請求書に設定しないと、FinishInvoice()が失敗し、戻り値を設定する必要があります。

DAO.GetInvoice()への2回目の呼び出しは、FinishInvoice()から呼び出され、は、テストの一部です。

このテストを実行すると、DAO.GetInvoice(1)に失敗します。期待される#1、実際の#0。私はコードをステップインし、DAO.GetInvoice()をコールすると、FinishInvoice()が呼び出され、プレゼンターのコードではなく私のテストコードでなければなりません。

私が変更した場合:

SetupResult.For(DAO.GetInvoice(1)).Return(invoice); 

をする:

Expect.Call(DAO.GetInvoice(1)).Return(invoice); 

それは動作しますが、設定(することはできませんがためにそれがちょうど必要とされているように、そのテストの一部であってはなりませんすべてのテストで必須ではないのでSetUpメソッドを使用してください)

私はExpect.Call()でそれを行う必要はないと思いますが、どのように設定するかを学びたいと思いますそれが欲しい。

答えて

0

DAOクラスの相互作用をテストするためには、as a mock and not as a stubを作成する必要があります。つまり、SetupResultを使用することはできません。あなたはあなただけRepeat-syntax使用できるメソッド呼び出しの順序を気にしない場合は

:あなたがメソッドの順序を気にしない場合

using (mocks.Record()) 
{ 
    SetupResult.For(view.Invoice).PropertyBehavior(); 
    Expect.Call(DAO.FinishInvoice(1)).Return(true); 
    Expect.Call(DAO.GetInvoice(1)).Return(invoice).Repeat.Any(); 
} 
using (mocks.Playback()) 
{ 
    Presenter presenter = new Presenter(view, DAO); 
    presenter.InitializeView(1); 
    presenter.FinishInvoice(); 
} 

を呼び出して、明示的にそれぞれの期待を指定する必要がありますOrdered-syntaxて:あなたはヨールコードで二回DAO.GetInvoiceを呼び出している場合

using (mocks.Record()) 
{  
    SetupResult.For(view.Invoice).PropertyBehavior(); 

    using (mocks.Ordered()) 
    { 
     Expect.Call(DAO.GetInvoice(1)).Return(invoice);  
     Expect.Call(DAO.FinishInvoice(1)).Return(true); 
     Expect.Call(DAO.GetInvoice(1)).Return(invoice); 
    } 
} 
using (mocks.Playback()) 
{ 
    Presenter presenter = new Presenter(view, DAO); 
    presenter.InitializeView(1); 
    presenter.FinishInvoice(); 
} 

しかし、私はそれがコードのにおいだと言うでしょう、そしてあなたはおそらくちょうど1つのコールにそれをリファクタリングになるはずです。

はまた、ここではこれがAAA-syntax from 3.5でどのように見えるかです:

//Arrange 
DAO.Stub(x => x.GetInvoice(1)).Return(true).Repeat.Any(); 

//Act 
Presenter presenter = new Presenter(view, DAO); 
presenter.InitializeView(1); 
presenter.FinishInvoice(); 

//Assert 
DAO.AssertWasCalled(x => x.FinishInvoice(1)); 
DAO.AssertWasCalled(x=> x.GetInvoice(1)); 

あなたは、これは多くの進歩して、そしてあなたもモックとスタブの両方としてモックを使用することができます見ることができるように。

+0

なぜ、GetInvoice()が2回呼び出されるのは、FinishInvoice()が請求書を変更するストアドプロシージャを呼び出し、変更を表示するために再フェッチする必要があるためです。また、これは単なるテストで、GetInvoice()への2つの呼び出しの間のタイムラインは表示されません。請求書をロードし、表示し、変更し、完了した後、再ロードして、完了した変更を表示します。 私のテストコードでは、ビューとdaoの両方がモックです。モックでSetupResult.For()を使用できないことに気づいていませんでした。私はその話題についてもっと読んでいくつもりです。ありがとう。 –

関連する問題