ASP.NET MVCでのHtmlHelpersのテスト
-
06-07-2019 - |
質問
自分のHtmlHelpersを(ユニット)テストする方法はありますか? (HtmlHelperによってレンダリングされた)カスタムコントロールが必要で、そのコントロールの要件を知っている場合、最初にテストを記述し、次にコードを記述する方法はありますか?それを行うための特定の(素敵な)方法はありますか?
価値はありますか?
解決
主な問題は、ヘルパーのメソッドを使用してルートや値を取得したり、別の拡張メソッドの結果を返したりする可能性があるため、HtmlHelperをモックする必要があることです。 HtmlHelperクラスには非常に多くのプロパティがあり、それらの一部はViewContextや現在のControllerのように非常に複雑です。
Ben Hartによるこの投稿では、Moqを使用してこのようなモックを作成する方法を説明しています。別の模擬フレームワークに簡単に翻訳できます。
これは、MVCフレームワークの変更に適応したRhino Mocksのバージョンです。完全にテストされているわけではありませんが、うまく機能していますが、完璧な結果を期待していません:
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData)
{
var mocks = new MockRepository();
var cc = mocks.DynamicMock<ControllerContext>(
mocks.DynamicMock<HttpContextBase>(),
new RouteData(),
mocks.DynamicMock<ControllerBase>());
var mockViewContext = mocks.DynamicMock<ViewContext>(
cc,
mocks.DynamicMock<IView>(),
viewData,
new TempDataDictionary());
var mockViewDataContainer = mocks.DynamicMock<IViewDataContainer>();
mockViewDataContainer.Expect(v => v.ViewData).Return(viewData);
return new HtmlHelper(mockViewContext, mockViewDataContainer);
}
他のヒント
誰かがHtmlHelper<T>
の作成方法を探しているなら(それが私が望んでいたことです)、ここに役立つかもしれない実装があります-私の型はModelという名前のクラスです:
public static HtmlHelper<Model> CreateHtmlHelper()
{
ViewDataDictionary vd = new ViewDataDictionary(new Model());
var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object);
var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object);
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData).Returns(vd);
return new HtmlHelper<Model>(viewContext, mockViewDataContainer.Object);
}
またはより一般的な実装:
public HtmlHelper<T> CreateHtmlHelper<T>() where T : new()
{
var vd = new ViewDataDictionary(new T());
var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object,
new RouteData(),
new Mock<ControllerBase>().Object);
var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object);
var mockViewDataContainer = new Mock<IViewDataContainer>();
mockViewDataContainer.Setup(v => v.ViewData).Returns(vd);
return new HtmlHelper<T>(viewContext, mockViewDataContainer.Object);
}
カスタムヘルパーを作成しています。これは、MoqおよびASP MVC 2でhttphelperをモックするために使用しているコードです。また、HttpRequestBaseのモックをパラメーターとして渡します。不要な場合は削除できます
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData, Mock requestMock) { var contextBaseMock = new Mock(); contextBaseMock.SetupGet(cb => cb.Request).Returns(requestMock.Object); var cc = new ControllerContext(contextBaseMock.Object, new RouteData(), new Mock().Object); var vctx = new ViewContext( cc, new Mock().Object, viewData, new TempDataDictionary(), new HtmlTextWriter(new StreamWriter(new MemoryStream()))); var mockViewDataContainer = new Mock(); mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData); return new HtmlHelper(vctx, mockViewDataContainer.Object); }
所属していません StackOverflow