2015-10-16 3 views
0

Ниже приведен фрагмент кода, для которого я хочу писать тесты:Как высмеять Request.IsAjaxRequest() в true с помощью FakeItEasy?

[HttpGet] 
public ActionResult Edit(string id) 
{ 
    if (Request.IsAjaxRequest()) 
    { 
     EditModel model = new EditModel();  
     ..... 
    } 
    return View(); 
} 

Я хочу писать тесты для этого действия, где я могу фальсифицировать результат Request.IsAjaxRequest() к истине, так что я могу писать тесты для отдыха кода действия.

Я пробовал следовать, но он не работает. _request.Headers всегда пусто, и Request.IsAjaxRequest() всегда возвращается ложь:

[Fact] 
public void Get_Edit_AjaxRequest_ExpectedActionCalled() 
{ 
    HttpRequestBase _request = A.Fake<HttpRequestBase>(); 
    _request.Headers.Add("X-Requested-With", "XMLHttpRequest"); 
    _controller.ControllerContext = A.Fake<ControllerContext>(); 
    _controller.ControllerContext.HttpContext = _request; 

    A.CallTo(() => _controller.Request).Returns(_request); 

    var result = _controller.Edit(1) as RedirectToRouteResult; 
} 

Я всегда получаю Request.IsAjaxRequest() как ложь. Любая помощь по этому поводу очень ценится. Спасибо

+0

Я пытаюсь воспроизвести, но имею большие проблемы. Я не парень MVC, и, возможно, часть моей проблемы заключается в том, что я не использую правильную версию (я использую все, что пришло с VS2013), но '_controller.ControllerContext.HttpContext = _request;' не компилируется ('HttpRequesteBase' не является' RequestContext'), а '_controller.Edit (1)' не компилируется, потому что 'Edit' принимает' string'. Можете ли вы указать, где я ошибаюсь, или исправить вопрос, чтобы он, по крайней мере, скомпилировался? –

ответ

2

Мне удалось запутать ошибки компиляции и использовать некоторую информацию из главы 10 FakeItEasy Succinctly, которая касается ASP.NET MVC.

Вообще говоря, классы ASP.NET MVC не разработаны таким образом, чтобы сделать их легко поддельными, но у меня есть тестовая настройка, которая вызывает IsAjaxRequest, чтобы вернуть true. Два основных препятствия заключались в том, что контроллер использовал объект запроса и чтобы объект запроса возвращал нужные нам заголовки. Первая часть не была сложной, но вторая требовала от нас, чтобы объект запроса использовал конкретный NameValueCollection. Поддельный, который он предоставлял по умолчанию, не был полезен, потому что правильные свойства не были виртуальными. К счастью, использование реального NameValueCollection сделало трюк.

Попробуйте это:

[Fact] 
public void Get_Edit_AjaxRequest_ExpectedActionCalled_Blair() 
{ 
    HttpRequestBase _request = A.Fake<HttpRequestBase>(); 

    // NameValueCollection is effectively unfakeable due to non-virtual properties, 
    // but a real one works just fine, so make sure the headers use one of those. 
    A.CallTo(() => _request.Headers).Returns(new NameValueCollection()); 
    _request.Headers["X-Requested-With"] = "XMLHttpRequest"; 

    var httpContext = A.Fake<HttpContextBase>(); 
    A.CallTo(() => httpContext.Request).Returns(_request); 

    _controller.ControllerContext = new ControllerContext(
     new RequestContext(httpContext, new RouteData()), 
     _controller); 

    var result = _controller.Edit(1) as RedirectToRouteResult; 
} 

Имейте в виду, что там будет много подводных камней, как это в рамках MVC, и продолжает фальсифицировать их, возможно, по-прежнему сложно. Вы можете найти более устойчивый подход - извлечь как можно больше своей логики, насколько это возможно, в простые старые тестируемые бизнес-классы, которые не полагаются на структуру MVC.

+1

Спасибо Блэр за предоставление решения .. и за ссылку на книгу .. это очень полезно ... – Nirman

 Смежные вопросы

  • Нет связанных вопросов^_^