2012-02-13 9 views
12

Estoy muy, muy nuevo a la unidad de pruebas y estoy tratando de escribir una prueba para un método bastante simple:¿Cómo realizo una prueba unitaria para probar un método que verifica los encabezados de solicitud?

public class myClass : RequireHttpsAttribute 
{ 
    public override void OnAuthorization(AuthoizationContext filterContext) 
    { 
     var request = filterContext.HttpContext.Request; 
     var header = Convert.ToBoolean(request.Headers["Special-Header-Name"]); 

     if (!(header || request.IsSecureConnection)) 
     { 
      HandleNonHttpsRequest(filterContext); 
     } 
    } 
} 

Este método, que hereda de la RequireHttpsAttribute, comprueba si una determinada cabecera está presente desde una página , si falta o es falso, y la página no es segura, llamará al HandleNonHttpsRequest, de lo contrario no hará nada.

Estamos utilizando Moq y Nunit para realizar pruebas. He encontrado algunos recursos para ayudar a construir un falso HttpContext con Moq, pero sinceramente no estoy seguro de cómo usarlo o dónde ir dentro de mis pruebas unitarias para asegurar que los falsos HttpContexts sean o no causen que el método HandleNonHttpsRequest llame.

Realmente aprecio cualquier orientación con este problema.

Respuesta

20
// arrange 
var context = new Mock<HttpContextBase>(); 
var request = new Mock<HttpRequestBase>(); 
var headers = new NameValueCollection 
{ 
    { "Special-Header-Name", "false" } 
}; 
request.Setup(x => x.Headers).Returns(headers); 
request.Setup(x => x.HttpMethod).Returns("GET"); 
request.Setup(x => x.Url).Returns(new Uri("http://www.example.com")); 
request.Setup(x => x.RawUrl).Returns("/home/index"); 
context.Setup(x => x.Request).Returns(request.Object); 
var controller = new Mock<ControllerBase>(); 

var actionDescriptor = new Mock<ActionDescriptor>(); 
var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object); 
var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object); 
var sut = new myClass(); 

// act 
sut.OnAuthorization(filterContext); 

// assert 
Assert.IsInstanceOfType(filterContext.Result, typeof(RedirectResult)); 
var redirectResult = (RedirectResult)filterContext.Result; 
Assert.AreEqual("https://www.example.com/home/index", redirectResult.Url); 
+1

+1 para señalando las secciones AAA de la prueba. – CodingWithSpike

+0

¡Gracias! Esto me envió en la dirección correcta para obtener algunas pruebas exitosas. – Dredj

1

Sí, utilizaría Moq y crearía un Mock<AuthorizationContext>. Necesitarás una serie de objetos falsos para configurar la solicitud falsa, sobre todo para especificar una NameValueCollection de encabezados falsos.

var request = new Mock<HttpRequestBase>(); 
request.SetupGet(c => c.Headers).Return(new NameValueCollection{ /* initialize values here */}); 
request.SetupGet(c => c.IsSecureConnection).Return(/*specify true or false depending on your test */); 

var httpContext = new Mock<HttpContextBase>(); 
httpContext.SetupGet(c => c.Request).Return(request.Object); 


var filterContext = new Mock<AuthorizationContext>(); 
filterContext.SetupGet(c => c.HttpContext).Return(httpContext.Object); 

var myclass = new myClass(); 
myClass.OnAuthorization(filterContext.Object); 

(lo siento si la sintaxis o el uso es ligeramente fuera; haciendo esto desde la parte superior de la cabeza)

Es posible que tenga que entrar y burlarse de cualquier miembro adicional en filterContext que HandleNonHttpsRequest invoca. Tengo dos recomendaciones para hacer esto, ya que a veces puede ser una molestia si el método que está probando está haciendo muchas cosas complejas en filterContext: 1) verificar visualmente y, si es lo suficientemente sencillo, simular todas las piezas invocadas 2) cree myClass.OnAuthorizationRequest, pero no implemente ningún código que no sea la llamada a HandleNonHttpsRequest. Siga haciendo la prueba y arreglando los miembros faltantes o incorrectamente burlados hasta que pase la prueba. Luego, implemente su lógica real para OnAuthorizationRequest, testing y fixing (repeat de enjuague) hasta que pase.

0

me encontré con un problema con the accepted solution usando ASP.NET MVC 4. Para resolverlo Me burlé atribuyen los artículos de contexto http contrario el sut.OnAuthorization estaba causando un objeto es una excepción indefinido:

MockHttpContext.Setup(x => x.Items) 
    .Returns(new System.Collections.Generic.Dictionary<object, object>()); 
Cuestiones relacionadas