Как выполнить модульное тестирование пользовательского ActionFilter в ASP.Net MVC - PullRequest
22 голосов
/ 14 декабря 2011

Итак, я создаю собственный ActionFilter, основанный в основном на этом проекте. http://www.codeproject.com/KB/aspnet/aspnet_mvc_restapi.aspx.

Мне нужен специальный фильтр действий, который использует заголовки http accept для возврата либо JSON, либо Xml.Типичное действие контроллера будет выглядеть так:

[AcceptVerbs(HttpVerbs.Get)]
[AcceptTypesAttribute(HttpContentTypes.Json, HttpContentTypes.Xml)]
public ActionResult Index()
{
    var articles = Service.GetRecentArticles();

    return View(articles);
}

Пользовательский фильтр переопределяет OnActionExecuted и сериализует объект (в статьях этого примера) как JSON или Xml.

Мой вопрос: как мне это проверить?

  1. Какие тесты я пишу?Я новичок в TDD и не уверен на 100%, что мне следует тестировать, а что нет.Я придумал AcceptsTypeFilterJson_RequestHeaderAcceptsJson_ReturnsJson(), AcceptsTypeFilterXml_RequestHeaderAcceptsXml_ReturnsXml() и AcceptsTypeFilter_AcceptsHeaderMismatch_ReturnsError406().
  2. Как проверить ActionFilter в MVC, который проверяет заголовки Http Accept?

Спасибо.

Ответы [ 2 ]

26 голосов
/ 14 декабря 2011

Вам просто нужно протестировать сам фильтр. Просто создайте экземпляр и вызовите метод OnActionExecuted() с тестовыми данными, а затем проверьте результат. Это помогает максимально разделить код. Большая часть тяжелой работы выполняется в классе CsvResult, который можно проверить индивидуально. Вам не нужно тестировать фильтр на реальном контроллере. Ответственность за выполнение этой работы лежит на структуре MVC.

public void AcceptsTypeFilterJson_RequestHeaderAcceptsJson_ReturnsJson()
{
    var context = new ActionExecutedContext();
    context.HttpContext = // mock an http context and set the accept-type. I don't know how to do this, but there are many questions about it.
    context.Result = new ViewResult(...); // What your controller would return
    var filter = new AcceptTypesAttribute(HttpContentTypes.Json);

    filter.OnActionExecuted(context);

    Assert.True(context.Result is JsonResult);
}
14 голосов
/ 10 апреля 2015

Я только что наткнулся на это сообщение в блоге , которое мне кажется правильным, он использует Мок

Редактировать

Хорошо, так что этот парень делает насмешку над HTTPContext, но нам также нужно настроить ContentType в запросе:

    // Mock out the context to run the action filter.
    var request = new Mock<HttpRequestBase>();
    request.SetupGet(r => r.ContentType).Returns("application/json");

    var httpContext = new Mock<HttpContextBase>();
    httpContext.SetupGet(c => c.Request).Returns(request.Object);

    var routeData = new RouteData(); //
    routeData.Values.Add("employeeId", "123");

    var actionExecutedContext = new Mock<ActionExecutedContext>();
    actionExecutedContext.SetupGet(r => r.RouteData).Returns(routeData);
    actionExecutedContext.SetupGet(c => c.HttpContext).Returns(httpContext.Object);

    var filter = new EmployeeGroupRestrictedActionFilterAttribute();

    filter.OnActionExecuted(actionExecutedContext.Object);

Примечание - я не проверял это сам

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