Подтвердить что ты не робот

Как сделать unit test собственный ActionFilter в ASP.Net MVC

Итак, я создаю пользовательский 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.

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

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

Спасибо.

4b9b3361

Ответ 1

Вам просто нужно проверить фильтр. Просто создайте экземпляр и вызовите метод 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);
}

Ответ 2

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

Edit

Хорошо, так что этот парень делает, издеваясь над 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);

Примечание. Я сам этого не тестировал.