2012-03-26 97 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>不提供任何属性和方法的实现。当设置属性的值时,没有任何事情发生,值是'丢失'。

另一种选择是提供假上下文,该假上下文是具有真实属性的具体类。