Тестирование HtmlHelpers в ASP.NET MVC - PullRequest
23 голосов
/ 07 ноября 2008

Есть ли способ (юнит) проверить мой собственный HtmlHelpers? В случае, когда я хотел бы иметь пользовательский элемент управления (предоставленный HtmlHelper), и я знаю требования для этого элемента управления, как я мог бы сначала написать тесты, а затем написать код? Есть ли конкретный (хороший) способ сделать это?

Стоит ли?

Ответы [ 3 ]

30 голосов
/ 14 апреля 2009

Основная проблема заключается в том, что вам приходится издеваться над HtmlHelper, поскольку вы можете использовать методы помощника для получения маршрутов или значений или возвращать результат другого метода расширения. Класс HtmlHelper имеет довольно много свойств, а некоторые из них довольно сложные, например ViewContext или текущий контроллер.

Это сообщение от Бена Харта , в котором объясняется, как создать такой макет с помощью Moq. Может быть легко переведено на другой фиктивный фреймворк.

Это моя версия Rhino Mocks, адаптированная к изменениям в MVC Framework. Он не полностью протестирован, но работает на меня, но не ожидайте отличных результатов:

    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);
    }
9 голосов
/ 11 мая 2011

Если кто-то ищет способ создания 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);
    }
0 голосов
/ 01 февраля 2011

Я создаю собственный помощник, и это код, который я использую для макета httphelper с помощью Moq и ASP MVC 2. Я также передаю в качестве параметра макет 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);
        }
...