2009-04-01 4 views
7

저는 Mocking 프레임 워크에 익숙하지 않고 RhinoMock을 사용하여 MVC App Unit Testing을 지원하기 시작했습니다.Rhino Mock을 사용하여 HttpContext.Application을 모의 사용하는 방법

나는 Scott Hanselmanns MVC Mock Helper을 사용하여 HttpContext를 조롱합니다. HttpContext의 Application 속성에 대해 필자는 (시간이 지나면) 필자가 필요로하는 것을 조롱했으나 멈추게되었습니다. 내 응용 프로그램에서

나는 응용 프로그램에서 개체를 저장하고 같은 컨트롤러 내에서 검색 :

이 내 MVC 응용 프로그램에서 위해 Application_Start에 생성됩니다
SomeObj foo = (SomeObj)Application["fooKey"]; 

.

테스트 설정에서 현재 첫 번째 대답 (명확성을 위해 추가 코드) 업데이트 된 다음 내가 할 내 단위 테스트 설정에서

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

내가 할 :

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

이 호출이 발생합니다 Application 개체에 대한 NullReference 예외입니다.

내 질문은 두 배 :

1)이 올바른 접근 아니면 내가 디자인/아키텍처 관점에서 잘못을했을가요?

2) 왜 작동하지 않습니까?!

미리 감사드립니다.

+1

내 대답을 편집했습니다. 그것을 확인하고 그것이 작동하는지 확인 – Randolpho

답변

1

너무 깊게 파고 있지 않으면이 모양이 대부분 올바른 것처럼 보입니다.

Application 속성은 HttpContextBase에서 가상이므로 Rhino에서 반환 값을 설정할 수 있습니다. HttpContextBase를 Scott Hanselmanns 게시와 조롱한다고 가정 할 때

  • 당신이 controllerToTest.ControllerContext에 대한 반환을 설정 했 : 정말 정보의 부족으로 추측된다

    을 유발할 수있는 요인은?

  • 에 대한 응답을 설정 했습니까? 개체 HttpContext 속성?
  • 에 대한 답장을 설정 했습니까 개체 응용 프로그램 속성?

내가 묻는 이유는 예상 설정을 할 때 일반적으로 테스트의 일부로 호출 할 개체에 대한 참조를 이미 가지고 있기 때문에 사용자가 자신의 테스트와 마찬가지로 속성 체인을 수행하지 않기 때문입니다. controllerToTest.ControllerContext.HttpContext. Expect() 전화.,

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

난 당신이 인덱서는 속성과 같은 일을 가정하고 생각 :

편집 :

내가 문제를보고 생각하고, 나는이 부분에 생각 그들이하지 않을 때. 당신은 정말이 같은 항목 속성에 전화를받을 appState 개체에 기대를 설정해야 할 일은 :

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

랜돌 포, 고마워. 컨트롤러 컨텍스트, httpContext 및 응용 프로그램 [내가 생각하기에]에 대한 반환 값을 설정했습니다. 명확성을 위해 몇 가지 추가 코드를 추가했습니다. – Lewis

+0

아, 알겠습니다. 나는 충분히 블로그 게시물을 읽지 않았다. – Randolpho

+0

다시 한번 Randolpho에게 감사드립니다. 나는 불행하게도, 당신의 모범을 얻지 못했습니다. 이후 HttpContext 및 자식 객체에 대한 내 자신의 모의 객체를 작성하는 것으로 되돌아 왔으며 그런 방식으로 성공하는 것이 더 성공했습니다. – Lewis

1

당신은 MOQ를 위해 아래 사용할 수 있습니다. HttpApplication을 조롱하는 데는 어느 정도 시간이 걸렸습니다. appState.Object는 return 메서드 인 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

죄송합니다. "FakeHttpSessionState"와 "CreateSession"은 어디에 정의되어 있습니까? – CmdrTallen