4

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

問題は、ASP.NETの場合のように、HttpResponseBase.End()をモックして処理を停止する方法がわからないことです。

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;
}
4

1 に答える 1

2

あなたが達成しようとしていることは少しわかりませんが、あなたの説明から、抽象化を特定の実装のように動作させようとしているように思えます。つまり、HttpResponse.End() には特定の動作があるため、モックにも同じ動作をさせたいということですか?

一般に、(RhinoMocks とは異なり) 順序付けられた期待値の概念がないため、Moq でこれを行うのは特に簡単ではありません。ただし、それには機能要求があります。

Callback を End メソッドの設定と一緒に使用して、モックのそれ以降の動作を決定するフラグを切り替えることができるかもしれませんが、それは特にきれいではありません。私は次のようなことを考えています:

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

ended次に、他のすべてのセットアップに、 true または falseに基づいてデュアル実装を持たせます。

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

  1. Moq を使用する代わりに、HttpResponseBase の Fake 実装を作成します。ロジックが埋め込まれた Test Double がより良いオプションのように聞こえる実装の特定の動作を期待しているようです。簡単に言えば、Fake は、意図した製品実装を模倣する半複雑なロジックを含めることができる Test Double です。Fakes やその他の Test Double については、優れたxUnit Test Patterns book で詳しく読むことができます。
  2. 最初の仮定を再考してください。クライアントを HttpResponseBase の特定の動作に非常に密接に結び付けているように聞こえるので、Liskov Substitution Principle に違反している可能性があります。ただし、'End' というメソッドには純粋なセマンティックを超えた特定の意味合いがあるため、私は間違っている可能性がありますが、それでも、より良い設計が可能かどうかを個人的に検討したいと思います。
于 2009-07-26T11:27:35.400 に答える