2012-03-26 8 views
11

Tengo un controlador dentro de MVC3 que necesita devolver un código de respuesta 500 si algo sale mal. Estoy haciendo esto devolviendo un objeto de vista y estableciendo el código de respuesta http a 500 (lo he comprobado en Firebug y todo está funcionando bien).Código de respuesta de prueba de unidad MVC3

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

    return View(); 
} 

El problema que tengo ahora es que necesito poder escribir una prueba de unidad que verifique el código de respuesta. He intentado acceder al código de respuesta de varias maneras diferentes, a través del objeto ViewResult y el contexto del controlador.

Ninguno de los dos sentidos me da el código de respuesta que he configurado en el controlador.

[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); 

} 

¿Cómo podría obtener el código de respuesta 500 del controlador o es más una prueba de integración?

Respuesta

33

¿Qué hay de hacerlo de una manera más MVCish:

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

y luego:

// 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); 

o si usted insiste en el uso del objeto de respuesta se podría crear una falsa uno:

// 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

Me gusta este enfoque, pregunta rápida sin embargo, si una acción del controlador devuelve tanto un código de estado como una vista con un modelo, ¿hay algún ¿manera de imitar tanto la respuesta del código de estado como el resultado de la vista/modelo? Estoy luchando por pensar en una opción sensata. – dougajmcdonald

+0

buena pregunta @dougajmcdonald. ¿Conseguiste una respuesta? – richardwhatever

0

¿Qué es FakeHttpObject()? ¿Es un simulacro creado con Moq? En ese caso, necesita configurar setters y getters para almacenar los valores reales en alguna parte. Mock<T> no proporciona ninguna implementación de propiedades y métodos. Al establecer un valor de propiedad, literalmente, no pasa nada y el valor se 'pierde'.

Otra opción es proporcionar un contexto falso que sea una clase concreta con propiedades reales.