2009-09-21 15 views
87
[TestMethod] 
public void Home_Message_Display_Unknown_User_when_coockie_does_not_exist() 
{ 
    var context = new Mock<HttpContextBase>(); 
    var request = new Mock<HttpRequestBase>(); 
    context 
     .Setup(c => c.Request) 
     .Returns(request.Object); 
    HomeController controller = new HomeController(); 

    controller.HttpContext = context; //Here I am getting an error (read only). 
    ... 
} 

私のベースコントローラは、このrequestContextを取得するInitializeのオーバーライドを持っています。私はこれを渡すことを試みているが、私は何か正しいことをしていない。Moqを使用してASP.NET MVCでHttpContextをモックするにはどうすればよいですか?

protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
{ 
    base.Initialize(requestContext); 
} 

ここで、Moqを使用してRequestContextとHttpContextを嘲笑する方法について詳しく知りたいですか?私はクッキーと一般的なコンテキストを模倣しようとしています。

答えて

52

HttpContextは読み取り専用ですが、実際には設定できるControllerContextから派生しています。

controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller); 
+0

これは、私がコントローラ上で模擬HttpContextを設定できるようにすることによって私のために働いていました。 –

32

要求、応答を作成しているHttpContextにそれらの両方を置く:ここ

HttpRequest httpRequest = new HttpRequest("", "http://mySomething/", ""); 
StringWriter stringWriter = new StringWriter(); 
HttpResponse httpResponse = new HttpResponse(stringWriter); 
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse); 
+0

質問は、HttpRequestではなく、* HttpRequestBaseのような*基本クラスについてです。なぜ、両方が自分自身で必要とされているのかわからなくて、彼らが "密封"されているのをさらに迷惑に思います。 LogonUserIdentityを設定する方法はありません:( –

+0

もし私が参照を整理していれば、リモートでも可能ですので、問題ではありません。 – 0100110010101

+1

@ChrisKimpton:最後の手段として、常に_reflection_ ;-) – Oliver

5

は、あなたがこれを設定する方法の例です:Mocking HttpContext HttpRequest and HttpResponse for UnitTests (using Moq)

は本当に役立つ拡張メソッドを注意してくださいこの模擬クラスの使用を簡略化するために:

var mockHttpContext = new API_Moq_HttpContext(); 

var httpContext = mockHttpContext.httpContext(); 

httpContext.request_Write("<html><body>".line()); 
httpContext.request_Write(" this is a web page".line()); 
httpContext.request_Write("</body></html>"); 

return httpContext.request_Read(); 

予想通りHttpModuleをが動作していることを確認するためにMOQを使ってユニットテストを記述する方法:Unit Test for HttpModule using Moq to wrap HttpRequest

アップデート:このAPIは

3

ここで私はControllerContextを使って偽のアプリケーションを渡していますH:

[TestClass] 
public class ClassTest 
{ 
    private Mock<ControllerContext> mockControllerContext; 
    private HomeController sut; 

    [TestInitialize] 
    public void TestInitialize() 
    { 
     mockControllerContext = new Mock<ControllerContext>(); 
     sut = new HomeController(); 
    } 
    [TestCleanup] 
    public void TestCleanup() 
    { 
     sut.Dispose(); 
     mockControllerContext = null; 
    } 
    [TestMethod] 
    public void Index_Should_Return_Default_View() 
    { 

     // Expectations 
     mockControllerContext.SetupGet(x => x.HttpContext.Request.ApplicationPath) 
      .Returns("/foo.com"); 
     sut.ControllerContext = mockControllerContext.Object; 

     // Act 
     var failure = sut.Index(); 

     // Assert 
     Assert.IsInstanceOfType(failure, typeof(ViewResult), "Index() did not return expected ViewResult."); 
    } 
} 
+1

なぜ偽のアプリケーションパスを渡す必要がありますか? –

+0

MVCコードはそれを実行し、存在しない場合はnull例外をスローします。 –

7

おかげユーザー0100110010101.

それは私のために働いたと、以下のコードのためのテストケースを書きながら、ここに私は問題があった:

var currentUrl = Request.Url.AbsoluteUri; 

そして、ここでは解決行です問題は

HomeController controller = new HomeController(); 
//Mock Request.Url.AbsoluteUri 
HttpRequest httpRequest = new HttpRequest("", "http://mySomething", ""); 
StringWriter stringWriter = new StringWriter(); 
HttpResponse httpResponse = new HttpResponse(stringWriter); 
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse); 
controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock), new RouteData(), controller); 

他の人にとって参考になるかもしれません。

関連する問題