2009-04-01 11 views
7

Sono nuovo di Mocking framework e ho iniziato a utilizzare RhinoMocks per assistere con i test dell'unità mobile di MVC.Come utilizzare Rhino Mock per simulare un HttpContext.Application

Sto usando Scott Hanselmanns MVC Mock Helper per aiutare a deridere HttpContext. Ho superato con successo (dopo un po 'di tempo) parte di ciò di cui ho bisogno, ma mi sono sbloccato quando si tratta della proprietà Application di HttpContext.

Nella mia applicazione devo conservare un oggetto nell'applicazione e recuperare entro un controller simile:

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

Questo viene creato su Application Start nella mia MVC App.

aggiornato a seguito prima risposta (codice aggiuntivo per chiarezza) Attualmente nella configurazione di prova che faccio:

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

Nella mia messa a punto di test di unità che faccio:

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

Questa chiamata tiri un'eccezione NullReference, per l'oggetto Application.

La mia domanda è duplice:

1) È questo l'approccio giusto o ho fatto qualcosa di sbagliato dal punto di vista di design/architettura?

2) Perché questo non funziona ?!

Grazie, in anticipo.

+1

Ho modificato la mia risposta; controllalo e vedi se funziona – Randolpho

risposta

1

Senza scavare troppo profondamente, questo sembra per lo più corretto.

La proprietà Application è virtuale su HttpContextBase, quindi dovresti essere in grado di impostare un valore di ritorno per esso da Rhino - Supponendo che stai prendendo in giro HttpContextBase come fa Scott Hanselmanns.

Alcune possibili cause, che sono in realtà solo supposizioni dalla mancanza di informazioni:

  • Ti è istituito ritorni per controllerToTest.ControllerContext?
  • Hai impostato un ritorno per che oggetti proprietà HttpContext?
  • Hai impostato un ritorno per che oggetti Proprietà dell'applicazione?

Il motivo che mi chiedo è che in genere quando si fa configurazioni aspettativa, si dispone già di riferimenti agli oggetti che verranno chiamati come parte del test, in modo da non fare una catena di proprietà come si fa con il tuo Chiamata controllerToTest.ControllerContext.HttpContext. Expect().

Edit:

mi sembra di vedere il problema, e penso che sia questa parte:

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

Penso che tu sia assumendo che indicizzatori funzionano allo stesso modo come proprietà, quando non lo fanno Che cosa si ha realmente bisogno di fare è impostare un'aspettativa sul vostro appState oggetto per ricevere una chiamata alla proprietà dell'oggetto, in questo modo:

// 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, grazie. Ho impostato i ritorni per il contesto del controller, httpContext e l'applicazione [penso]. Ho aggiunto qualche codice aggiuntivo per chiarezza. – Lewis

+0

Oh, capisco; Non ho letto abbastanza sul blog. – Randolpho

+0

Grazie ancora Randolpho. Sfortunatamente non sono riuscito a far funzionare il tuo esempio. Da allora sono tornato a scrivere i miei oggetti Mock per HttpContext e gli oggetti figlio e sto avendo più successo a fare le cose in questo modo. – Lewis

1

è possibile utilizzare il seguente per Moq. Mi ci è voluto un po 'come schernire HttpApplication e l'appState.Object è il metodo di ritorno 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

Scusa se sono denso dove sono definiti "FakeHttpSessionState" e "CreateSession"? – CmdrTallen

Problemi correlati