2012-03-26 121 views
11

我有一個MVC3內的控制器,如果出現問題,需要返回響應代碼500。我通過返回一個視圖對象並將http響應代碼設置爲等於500(我已經在螢火蟲中檢查過,並且所有工作都很好)來做到這一點。MVC3單元測試響應代碼

public ActionResult http500() 
{ 
    ControllerContext.HttpContext.Response.StatusCode = 500; 
    ControllerContext.HttpContext.Response.StatusDescription = "An error occurred whilst processing your request."; 

    return View(); 
} 

我現在的問題是我需要能夠編寫一個單元測試,檢查響應代碼。我曾嘗試以幾種不同的方式通過ViewResult對象和Controller上下文訪問響應代碼。

兩種方法都不能給我我在控制器中設置的響應代碼。

[TestMethod()] 
public void http500Test() 
{ 
    var controller = new ErrorController(); 
    controller.ControllerContext = new ControllerContext(FakeHttpObject(), new RouteData(), controller); 


    ViewResult actual = controller.http500() as ViewResult; 
    Assert.AreEqual(controller.ControllerContext.HttpContext.Response.StatusCode, 500); 

} 

我該如何去從控制器獲取響應代碼500,或者這是更多的集成測試的事情。

回答

33

如何更MVCish方式做:

public ActionResult Http500() 
{ 
    return new HttpStatusCodeResult(500, "An error occurred whilst processing your request."); 
} 

然後:

// arrange 
var sut = new HomeController(); 

// act 
var actual = sut.Http500(); 

// assert 
Assert.IsInstanceOfType(actual, typeof(HttpStatusCodeResult)); 
var httpResult = actual as HttpStatusCodeResult; 
Assert.AreEqual(500, httpResult.StatusCode); 
Assert.AreEqual("An error occurred whilst processing your request.", httpResult.StatusDescription); 

,或者如果你堅持使用響應對象,你可以創建一個假的:

// arrange 
var sut = new HomeController(); 
var request = new HttpRequest("", "http://example.com/", ""); 
var response = new HttpResponse(TextWriter.Null); 
var httpContext = new HttpContextWrapper(new HttpContext(request, response)); 
sut.ControllerContext = new ControllerContext(httpContext, new RouteData(), sut); 

// act 
var actual = sut.Http500(); 

// assert 
Assert.AreEqual(500, response.StatusCode); 
Assert.AreEqual("An error occurred whilst processing your request.", response.StatusDescription); 
+2

我喜歡這種方法,但問題很簡單,如果一個控制器動作同時返回一個狀態碼和一個模型視圖,是否有一個sens可以用模式來模擬狀態碼響應和視圖/模型結果嗎?我正在努力想出一個明智的選擇。 – dougajmcdonald 2013-10-13 09:49:46

+0

好問題@dougajmcdonald。你有答案嗎? – richardwhatever 2017-09-05 12:25:38

0

什麼是FakeHttpObject()?這是使用Moq創建的模擬嗎?在這種情況下,你需要設置setter和getters來存儲實際的值。 Mock<T>不提供任何屬性和方法的實現。當設置屬性的值時,沒有任何事情發生,值是'丟失'。

另一種選擇是提供假上下文,該假上下文是具有真實屬性的具體類。