Как вы получаете модульные тесты для использования маршрутов в ASP.NET MVC? - PullRequest
2 голосов
/ 07 декабря 2009

Я пишу модульные тесты для моего приложения ASP.NET MVC, в частности, я тестирую метод расширения HtmlHelper, который я написал. Внутри метода расширения есть строка:

var innerHtml = htmlHelper.ActionLink(text, action, controller, routeValues, null);

Когда я запускаю это в моем модульном тесте, href сгенерированного URL остается пустым независимо от переданного действия или контроллера.

Вот мой тестовый модуль:

var page = CreateProductDataPage(); //returns ProductDataPage object
var htmlHelper = Http.CreateHtmlHelperWithMocks<ProductDataPage>(new ViewDataDictionary<ProductDataPage>(page), false);
var result = htmlHelper.ProductListingBreadcrumb(true, null, null);

Вот метод CreateHtmlHelperWithMocks:

public static HtmlHelper<T> CreateHtmlHelperWithMocks<T>(ViewDataDictionary<T> viewData, bool isLoggedIn) where T : class
{
    var mockViewDataContainer = new Mock<IViewDataContainer>();
    mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData);

    return new HtmlHelper<T>(GetViewContextMock(viewData, isLoggedIn).Object, mockViewDataContainer.Object);
}

Наконец, вот метод GetViewContextMock:

public static Mock<ViewContext> GetViewContextMock(ViewDataDictionary viewData, bool isLoggedIn)
{
    var mock = new Mock<ViewContext>();

    mock.SetupGet(v => v.HttpContext).Returns(GetHttpContextMock(isLoggedIn).Object);
    mock.SetupGet(v => v.Controller).Returns(new Mock<ControllerBase>().Object);
    mock.SetupGet(v => v.View).Returns(new Mock<IView>().Object);
    mock.SetupGet(v => v.ViewData).Returns(viewData);
    mock.SetupGet(v => v.TempData).Returns(new TempDataDictionary());
    mock.SetupGet(v => v.RouteData).Returns(new RouteData());

    return mock;
}

Ответы [ 2 ]

4 голосов
/ 07 декабря 2009

Обновление: разобрался. Какая боль в $$. На случай, если кто-то еще попытается сделать это ...

Первым шагом было добавление коллекции маршрутов из global.asax при создании макета HtmlHelper.

    public static HtmlHelper<T> CreateHtmlHelperWithMocks<T>(ViewDataDictionary<T> viewData, bool isLoggedIn) where T : class
    {
        var mockViewDataContainer = new Mock<IViewDataContainer>();
        mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData);

        //These next two lines are key:
        var routeCollection = new RouteCollection();
        MvcApplication.RegisterRoutes(routeCollection);

        return new HtmlHelper<T>(GetViewContextMock(viewData, isLoggedIn).Object, mockViewDataContainer.Object, routeCollection);
    }

Затем мне нужно было убедиться, что макет HttpContext вернул результат для свойства ApplicationPath запроса и метода ApplyAppPathModifier Ответа.

    public static Mock<HttpContextBase> GetHttpContextMock(bool isLoggedIn)
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        var principal = AuthenticationAndAuthorization.GetPrincipleMock(isLoggedIn);

        //These next two lines are required for the routing to generate valid URLs, apparently:
        request.SetupGet(r => r.ApplicationPath).Returns("/");
        response.Setup(r => r.ApplyAppPathModifier(It.IsAny<string>())).Returns((string r) => r);

        context.SetupGet(c => c.Request).Returns(request.Object);
        context.SetupGet(c => c.Response).Returns(response.Object);
        context.SetupGet(c => c.Session).Returns(session.Object);
        context.SetupGet(c => c.Server).Returns(server.Object);
        context.SetupGet(c => c.User).Returns(principal.Object);

        return context;
    }
0 голосов
/ 07 декабря 2009

Я писал об этом с Rhino.Mocks около месяца назад. Дополнительную информацию о том, как я справляюсь с этим, вы можете найти по адресу http://farm -fresh-code.blogspot.com / 2009/10 / mocking-htmlhelper-class-with.html . По сути, мое решение состоит в том, чтобы предоставить все в макете, как в RouteData, так и через ApplyAppPathModifier для объекта Response, подключенного к помощнику по макету. На самом деле это скорее фальшивый помощник, основанный на базовых заглушках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...