23

自分の HtmlHelpers を (ユニット) テストする方法はありますか? カスタム コントロール (HtmlHelper でレンダリング) が必要で、そのコントロールの要件がわかっている場合、最初にテストを作成してからコードを作成するにはどうすればよいでしょうか? それを行うための特定の(いい)方法はありますか?

それは価値がありますか?

4

3 に答える 3

30

主な問題は、ヘルパーのメソッドを使用してルートまたは値を取得したり、別の拡張メソッドの結果を返したりする可能性があるため、HtmlHelper をモックする必要があることです。HtmlHelper クラスには非常に多くのプロパティがあり、そのうちのいくつかは ViewContext や現在の Controller のように非常に複雑です。

Moq を使用してそのようなモックを作成する方法を説明するBen Hart のこの投稿。別のモック フレームワークに簡単に変換できます。

これは、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);
    }
于 2009-04-14T11:47:24.313 に答える
9

誰かが作成方法を探している場合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);
    }
于 2011-05-11T00:40:45.173 に答える
0

カスタム ヘルパーを作成しています。これは、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 = 新しい ControllerContext(contextBaseMock.Object,
                                            新しい RouteData(),
                                            new Mock().Object);
            var vctx = 新しい ViewContext(
                cc、
                new Mock().Object,
                ビューデータ、
                新しい TempDataDictionary(),
                new HtmlTextWriter(new StreamWriter(new MemoryStream())));

            var mockViewDataContainer = new Mock();

            mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData);

            return new HtmlHelper(vctx, mockViewDataContainer.Object);
        }
于 2011-02-01T13:54:59.967 に答える