moqでコントローラーコンテキストをモックする方法
-
05-07-2019 - |
質問
私はMOQフレームワークを試していますが、今のところ障壁にぶつかりました。 ViewNameプロパティの実際の値が空の文字列であるため、次の単体テストは失敗します。
テストに合格しない理由について、誰かが正しい方向を教えてくれませんか?
[TestMethod]
public void Can_Navigate_To_About_Page()
{
var request = new Mock<HttpRequestBase>();
request.Setup(r => r.HttpMethod).Returns("GET");
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(c => c.Request).Returns(request.Object);
var controllerContext = new ControllerContext(mockHttpContext.Object,
new RouteData(),
new Mock<ControllerBase>().Object);
var controller = new HomeController();
controller.ControllerContext = controllerContext;
var result = controller.About() as ViewResult;
Assert.AreEqual("About", result.ViewName);
}
次の場合も、空のViewNameが生成されます。
HomeController controller = new HomeController();
ViewResult result = controller.About() as ViewResult;
Assert.IsNotNull(result);
Assert.AreEqual("About", result.ViewName);
モックと優れたTTDを示すWeb上の例から、上記の最初の単体テストの例のいずれかを機能させるために必要な他の配管について混乱しているだけです。
乾杯、
アンドリュー
解決
テストが失敗する理由は、ViewNameを明示的に指定しない場合にViewNameを決定するのはフレームワークの深さにあるためです。より正確には、ビューエンジンでは信じています。そのため、これを現状のままテストするには、リクエストパイプラインをもっとモックアウトする必要があります。
デフォルトの設定に依存せず、ビューを明示的に指定することをお勧めします。
return View("About");
その後、値はモックなしでテストするために存在します:
var controller = new HomeController();
var result = controller.About() as ViewResult;
Assert.AreEqual("About", result.ViewName);
他のヒント
これは、MVCフレームワークがどのように機能するかについて想定しているためです。ビューを見つけるために規則に依存している場合、フレームワークは ExecuteResult()
が呼び出されるまで、実際にはViewNameプロパティを String.Empty
のままにします。
このコードは、ViewResultBase.ExecuteResult の68行目で確認できます。 "nofollow noreferrer"> MVCソース:
if (String.IsNullOrEmpty(ViewName)) {
ViewName = context.RouteData.GetRequiredString("action");
}
さらに、テスト対象に注意する必要があります。経験則として、フレームワークのコードではなく、作成するコードのテストに焦点を当てる必要があります。慣例によりビュー名が正しく解決されていることを確認するテストは、実際にはフレームワーク自体の単体テストであり、フレームワーク上に構築されたアプリケーションではありません。
MVCでモッキングを使用する良い方法を探している場合は、ルートのテストを検討することをお勧めします(ここでやろうとしているように見えます)。 Phil Haackの投稿を見つけることができます。このテーマだけについて始めましょう。