2009-07-25 12 views
4

私はMoqを使ってHttpResponseBaseのモックオブジェクトを作成しています。私は私のライブラリでHttpResponseBase.End()が呼び出されたことをテストできるようにする必要があります。これを行うには、呼び出しの前にテキストを指定し、その後にテキストを指定します。次に、HttpResponseBase.OutputにEnd()を呼び出す前のテキストのみが存在することを確認します。HttpResponseBase.End()をどうやって模擬しますか?

問題は、私はHttpResponseBase.End()を模倣して、ASP.NETでの処理のように処理を停止する方法を見つけられません。

public static HttpResponseBase CreateHttpResponseBase() { 
    var mock = new Mock<HttpResponseBase>(); 
    StringWriter output = new StringWriter(); 

    mock.SetupProperty(x => x.StatusCode); 
    mock.SetupGet(x => x.Output).Returns(output); 
    mock.Setup(x => x.End()) /* what do I put here? */; 
    mock.Setup(x => x.Write(It.IsAny<string>())) 
     .Callback<string>(s => output.Write(s)); 

    return mock.Object; 
} 

答えて

2

それはあなたが達成しようとしている何であるか私には少しは不明ですが、特定の実装のように動作するあなたの抽象化を取得しようとしているようなあなたの記述から、それが聞こえます。つまり、HttpResponse.End()には特定の動作があるため、Mockに同じ動作をさせたいのですか?

一般的に、Moqではこれはあまり簡単ではありません。なぜなら、(RhinoMocksとは異なり)順序付けられた期待の概念がないからです。しかし、feature request for itがあります。

コールバックを使用して、Endメソッドを設定して、モックのそれ以上の動作を決定するフラグを切り替えることができますが、それは特に魅力的ではありません。私はこのような何かを考えている:

bool ended = false; 
var mock = new Mock<HttpResponseBase>(); 
mock.Setup(x => x.End()).Callback(() => ended = true); 
// Other setups involving 'ended' and Callbacks 

そして、他のすべてのセットアップがendedが真か偽であるかどうかに基づいて、デュアルimplementatationsを持っています。

これはかなり醜いので、私は真剣にこの時点で私の選択肢を再考したいと思います。少なくとも2つの方向があります:

  1. Moqを使用する代わりにHttpResponseBaseの偽の実装を作成してください。組み込みロジックを持つTest Doubleがより良いオプションのように聞こえるような実装のこのような特定の動作を期待しているように思えます。まもなく、FakeはTest Doubleであり、意図された本番の実装を模倣する準複雑なロジックを含むことができます。優れたxUnit Test Patterns本でFakeやその他のTest Doublesの詳細を読むことができます。
  2. 最初の前提条件を再考してください。クライアントがHttpResponseBaseの特定の動作に非常に密接に結びついているように私には聞こえるので、Liskov Substitution Principleに違反している可能性があります。しかし、私は誤解を招くかもしれません。というのは、「終わり」と呼ばれる方法は純粋に意味論を超えた意味を持ちますが、より良い設計が可能であるかどうかを個人的に考えています。
+0

ありがとうございます!フラグを設定するのが最も簡単な方法です。 –

関連する問題