2011-07-26 10 views
6

これは状況です。私は非同期呼び出しをしていましたので、テストするために中間層を作成する必要がありました。Moockを使用して模擬オブジェクトのメソッド実装を定義する

request.BeginGetResponse(new AsyncCallback(LoginCallback), requestState); 

だから、本当の要求なしでこれをテストすることができるようにするために、私はモックできるインターフェイスを作成しました。

public interface IRequestSender 
    { 
     void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState); 
    } 

は、その後の実装に私は上記の1つのように呼び出すと、私は関係なく、要求が有効であるかどうか、私のコールバックメソッドを呼び出すために、いくつかのモッククラスを提供することができます使用することができます。私のモッククラスはこのように見えます。

public class RequestSenderMock : IRequestSender 
    { 
     public void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) 
     { 
      var result = new Mock<IAsyncResult>(); 
      result.Setup(x => x.AsyncState).Returns(requestState); 
      internalCallback(result.Object); 
     } 
    } 

単体テストでモックオブジェクトを簡単に作成して使用できるようになりました。しかし、私が作成するとき

var sender = new Mock<RequestSenderMock>(); 

このオブジェクトの呼び出し回数を確認することができません。

sender.Verify(x => x.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()), Times.Once()); 

私の方法は仮想である必要があると言われています。 メソッドを仮想化せずにこれを行う方法はありますか?インタフェースを使用しているときに、何らかの形でメソッドの実装を指定することができれば最高です。

var sender = new Mock<IRequestSender>(); 

これは何とかセットアップメソッドや他の方法でこのモックオブジェクトを実装するためのものです。単に私のモッククラスを削除するよりも。 これは可能ですか?何を指示してるんですか?

答えて

8

マニュアルモックを作成し、モックフレームワークを使ってそれをモックする(モックを模擬する)ことは紛らわしいと思います。私はあなたのカスタム関数をいくつかのユーティリティクラスに移動し、代わりにコールバックを使用することを検討します。

例:

public class RequestSenderHelpers 
{ 
    public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) 
    { 
     var result = new Mock<IAsyncResult>(); 
     result.Setup(x => x.AsyncState).Returns(requestState); 
     internalCallback(result.Object); 
    } 

} 

    [Test] 
    public void Callback_VerifyingWithMethodImplementation_VerifyWorks() 
    { 
     // arrange 
     var sender = new Mock<IRequestSender>(); 
     sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(RequestSenderHelpers.Send); 

     // act 
     sender.Object.Send(null, delegate {}, null); 

     // assert 
     sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())); 
    } 

あなたが拡張メソッドにメソッドの設定をラップし、それに応じてテストを変更することができ、詳細設定避けるために:

public static class RequestSenderHelpers 
{ 
    public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState) 
    { 
     var result = new Mock<IAsyncResult>(); 
     result.Setup(x => x.AsyncState).Returns(requestState); 
     internalCallback(result.Object); 
    } 

    public static void SetupSendWithMockedAsyncResult(this Mock<IRequestSender> sender) 
    { 
     sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(Send);    
    } 

} 

    [Test] 
    public void Callback_VerifyingWithMethodImplementation_VerifyWorks() 
    { 
     // arrange 
     var sender = new Mock<IRequestSender>(); 
     sender.SetupSendWithMockedAsyncResult(); 

     // act 
     sender.Object.Send(null, delegate {}, null); 

     // assert 
     sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())); 
    } 
+0

おかげで、それは私がまさに必要です。 :) – Vajda

関連する問題