2015-10-16 71 views
0

下面是我想要編寫單元測試代碼片段:如何使用FakeItEasy模擬Request.IsAjaxRequest()爲true?

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

我想編寫單元測試這個動作,我可以僞造的Request.IsAjaxRequest()到真正的結果,這樣我可以寫其他測試的行爲代碼。

我試過以下,但它不起作用。 _request.Headers總是空的,並且Request.IsAjaxRequest()總是返回false:

[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

我設法混淆了編譯錯誤,並使用FakeItEasy Succinctly的第10章中的一些信息,這些信息都是關於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

相關問題