2009-04-01 12 views
7

Soy nuevo en los frameworks de Mocking y he empezado a utilizar RhinoMocks para ayudar con mi MVC App Unit Testing.Cómo usar Rhino Mocks para simular una HttpContext.Application

Estoy usando Scott Hanselmanns MVC Mock Helper para ayudar a burlarse del HttpContext. He tenido éxito (después de un tiempo) burlado de algo de lo que necesito, pero me he deshecho de la propiedad de la aplicación HttpContext.

En mi aplicación almacenar un objeto en la aplicación y recuperarlo dentro de un controlador como:

SomeObj foo = (SomeObj)Application["fooKey"]; 

Esto se crea en Application_Start en mi aplicación MVC.

actualizados tras la primera respuesta (código adicional para mayor claridad) Actualmente en la configuración de la prueba que hago:

HttpContextBase mockHttpBase = mocks.FakeHttpContext(); 
controllerToTest = new SomeController(); 
mocks.SetFakeControllerContext(controllerToTest); 


HttpApplicationStateBase appState = 
    MockRepository.GenerateStub<HttpApplicationStateBase>(); 

Globals tmpAppGlobals = 
    new Globals(); 

mockHttpBase.Expect(ctx => ctx.Application).Return(appState); 
mockHttpBase.Expect(ctx => ctx.Application[Globals.GlobalsKey]). 
    Return(tmpAppGlobals); 

En mi configuración de prueba de unidad que hago:

Globals tmpAppGlobals = new Globals(); 
controllerToTest.ControllerContext.HttpContext. 
      Expect(ctx => ctx.Application[Globals.GlobalsKey]). 
Return(tmpAppGlobals); 

Esta llamada tiros una Excepción de referencia nula para el objeto Aplicación.

Mi pregunta es doble:

1) ¿Es este el enfoque correcto o he hecho algo mal desde una perspectiva de diseño/arquitectura?

2) ¿Por qué esto no funciona ?!

Gracias, de antemano.

+1

He editado mi respuesta; compruébelo y vea si funciona – Randolpho

Respuesta

1

Sin ahondar demasiado, parece bastante correcto.

La propiedad de la aplicación es virtual en HttpContextBase, por lo que debería poder establecer un valor de retorno para ella desde Rhino, suponiendo que se está burlando de HttpContextBase como hace la publicación de Scott Hanselmanns.

Algunas causas posibles, que en realidad sólo son conjeturas debido a la falta de información:

  • ¿Creó devoluciones para controllerToTest.ControllerContext?
  • ¿Ha configurado un retorno para que objetos propiedad HttpContext?
  • ¿Ha configurado un retorno para que objetos Propiedad de la aplicación?

La razón que pido es que normalmente cuando haces configuraciones de expectativas, que ya tiene referencias a los objetos que serán llamadas como parte de la prueba, por lo que no haría una cadena de propiedad como lo hace con su controllerToTest.ControllerContext.HttpContext. Expect() llamada.

Editar:

Creo que veo el problema, y ​​yo creo que es con esta parte:

Expect(ctx => ctx.Application[Globals.GlobalsKey])

Creo que estás asumiendo que los indexadores funcionan igual que las propiedades, cuando no lo hacen Lo que realmente necesita hacer es configurar una expectativa en el objeto appState para recibir una llamada a la propiedad de artículos, como este:

// setup expectations -- assumes some of the expectations and mocks 
// the from original question 
mockHttpBase.Expect(ctx => ctx.Application).Return(appState); 
appState.Expect(ctx => ctx.Item(Globals.GlobalsKey)).Return(tmpAppGlobals); 

// run the test 
+1

Randolpho, gracias. He configurado los retornos para el contexto del controlador, httpContext y la aplicación [Creo]. He agregado un código adicional para mayor claridad. – Lewis

+0

Oh, ya veo; No leí la publicación del blog por completo. – Randolpho

+0

Gracias de nuevo Randolpho. No pude conseguir tu ejemplo para trabajar, desafortunadamente. Desde entonces, volví a escribir mis propios objetos simulados para HttpContext y objetos secundarios y estoy teniendo más éxito haciendo las cosas de esa manera. – Lewis

1

usted podría utilizar el siguiente para Moq. Me tomó un tiempo cómo simular la aplicación Http, y el appState.Object es el método de retorno duh!

public static HttpContextBase FakeHttpContext() 
    { 
     var context = new Mock<HttpContextBase>(); 
     var request = new Mock<HttpRequestBase>(); 
     var response = new Mock<HttpResponseBase>(); 
     var session = new FakeHttpSessionState(); 
     var server = new Mock<HttpServerUtilityBase>(); 
     var appState = new Mock<HttpApplicationStateBase>(); 

     context.Setup(ctx => ctx.Request).Returns(request.Object); 
     context.Setup(ctx => ctx.Response).Returns(response.Object); 
     context.Setup(ctx => ctx.Session).Returns(session); 
     context.Setup(ctx => ctx.Server).Returns(server.Object); 
     context.Setup(ctx => ctx.Application).Returns(appState.Object); 

     //emulate session (HttpContext.Current.Session) 
     var contx = new HttpContext(new MyApp.NUnit.Tests.Fakes.FakeHttpWorkerRequest()); 
     contx.Items["AspSession"] = CreateSession(); 

     HttpContext.Current = contx; 

     return context.Object; 
    } 
+2

Lo siento, soy denso, ¿dónde se define "FakeHttpSessionState" y "CreateSession"? – CmdrTallen

Cuestiones relacionadas