2009-04-01 5 views
7

私はMockingフレームワークが初めてで、RhinoMockを使用してMVCアプリケーションユニットテストを支援しました。Rhino Mocksを使用してHttpContext.Applicationをモックする方法

私はScott Hanselmanns MVC Mock Helperを使用して、HttpContextを嘲笑しています。 HttpContextのApplicationプロパティには、私が必要とするもののいくつかを嘲笑してしまいましたが、(しばらくして)うまくいきませんでした。私のアプリケーションで

私は、アプリケーション内のオブジェクトを保存などコントローラー以内にそれを取得:

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

これは私のMVCアプリケーションでのApplication_Startに作成されます。この呼び出しはスロー

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

:私は私のユニットテストのセットアップで

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

:私はテスト・セットアップで現在FIRST ANSWER(わかりやすくするために追加のコード) を次の更新

ApplicationオブジェクトのNullReference例外。

私の質問です2倍:

1)、これは適切なアプローチや、私が設計/アーキテクチャの観点から、何か間違ったことをしましたか?

2)なぜこれが機能しないのですか?

ありがとうございます。

+1

回答を編集しました。それを確認し、それが動作するかどうかを確認 – Randolpho

答えて

1

深く掘り下げることなく、これはほぼ正しいように見えます。

アプリケーションプロパティはHttpContextBase上では仮想的なので、Rhinoからの戻り値を設定できるはずです - HttpContextBaseをScott Hanselmannsの投稿と同じように偽装していると仮定します。

本当にただ情報の不足から推測されているいくつかの原因が考え、:

  • あなたは controllerToTest.ControllerContextのためのリターンを設定しましたか?
  • の返品を設定しましたか? オブジェクトHttpContextプロパティ?
  • の返品を設定しましたか? オブジェクトアプリケーションのプロパティ?

私が尋ねる理由は、典型的には期待設定を行うときに、テストの一部として呼び出されるオブジェクトへの参照が既に存在しているため、あなたのようにプロパティチェーンを実行しないcontrollerToTest.ControllerContext.HttpContext. Expect()が呼び出されます。

編集:

私は問題を参照してくださいと思うし、私はそれがこの部分でだと思う:

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

私はあなたがインデクサは、プロパティと同じように動作することを想定していると思います、彼らがしないとき。

// 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オブジェクトと子オブジェクトのための自分自身のMockオブジェクトを作成することに戻り、そのようなことをより成功させています。 – Lewis

1

あなたが部品番号については、以下を使用することができます。あなたが本当に行う必要があることは、このように、Itemプロパティへの呼び出しを受け取るためにあなたのappStateオブジェクトの期待を設定されています。しばらく私はHttpApplicationを模擬する方法を取った、そしてappState.Objectは戻りメソッドです!

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

関連する問題