2013-08-07 11 views
7

私はMOQを初めて使っていますが、単体テストのためにNUnitを使っています。MOQ - Mocking MVC Controllerのレスポンス.Cookies.Clear()

「オブジェクトのインスタンスにオブジェクトが設定されていません」というエラーメッセージが表示される以下の行を除いて、コントローラのすべての部分が嘲笑されています。

Response.Cookies.Clear(); 

私は私がこれまでに(このフォーラムには良い人々に非常に多くのおかげで)accrossに来ている他のすべてのために働くのコントローラコンテキストを模擬するために、次の拡張メソッドを持っています。

public static int SetUpForTest(this System.Web.Mvc.Controller ctl, string username, TestingUtility.Roles role) 
    { 
     var routes = new RouteCollection(); 
     MvcApplication.RegisterRoutes(routes); 

     var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     request.SetupGet(x => x.ApplicationPath).Returns("/"); 
     request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
     request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection()); 

     var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url); 
     // response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work 

     var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
     context.SetupGet(x => x.Request).Returns(request.Object); 
     context.SetupGet(x => x.Response).Returns(response.Object); 
     context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method 

     // 
     // Mock the controller context (using the objects mocked above) 
     // 
     var moqCtx = new Mock<ControllerContext>(context.Object, new RouteData(), ctl); 
     moqCtx.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(username); 
     moqCtx.SetupGet(p => p.HttpContext.User.Identity.IsAuthenticated).Returns(true); 
     if (!string.IsNullOrEmpty(role.ToString())) 
      moqCtx.Setup(p => p.HttpContext.User.IsInRole(role.ToString())).Returns(true); 

     // 
     // Pass the mocked ControllerContext and create UrlHelper for the controller and return 
     // 
     ctl.ControllerContext = moqCtx.Object; 
     ctl.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes); 
     return 1; 
    } 

あなたは私が助けていないクッキーコレクションの「取得」を模擬しようとした上で見ることができるように。

また、実際のClear()メソッドは、仮想メソッドではないため、非難されることはありません。

明らかに、私はクッキーがクリアされていることをテストしたくない、私はテストでそれを無視できるようにしたい。

おかげで、

+0

は、あなたがこの質問を見たことがあり()cookies.Clear行うとき、これは私の作品:http://stackoverflow.com/questions/1228179/mocking-httpcontextbase-with-moq – Halvard

+0

ありがとうをレスポンスが返ってきましたが、私はリンクの例を見てきましたが、上記のコントローラーコンテキストを嘲笑することで私がやったことはありません。私が何かが欠けているなら、正しい方向に私を指差してください! – Greg

+0

コードのその部分に(例えば)HttpContext.Currentではなく模擬されたコンテキストが得られていますか?何が間違っているのかちょうどアイデア。 – JuhaKangas

答えて

14

私は

  var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
     request.SetupGet(x => x.ApplicationPath).Returns("/"); 
     request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
     request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection()); 

     var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
     response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url); 
     // response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work 

     var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
     context.SetupGet(x => x.Request).Returns(request.Object); 
     context.SetupGet(x => x.Response).Returns(response.Object); 
     context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method 
     context.SetupGet(p => p.User.Identity.Name).Returns("blah"); 
     context.SetupGet(p => p.User.Identity.IsAuthenticated).Returns(true); 

     var rc = new RequestContext(context.Object, new RouteData()); 

     controller.ControllerContext = new ControllerContext(rc, controller); 
+0

ありがとうございました - あなたの例で示したように、ソリューションはHttpContextBaseだけを模倣し、ControllerContextは模倣しませんでした。彼の答えがHalvardのおかげで正しい方向へ向いてくれた – Greg

0

グレッグ(これは...半分しか答えですが、コメント欄には大きすぎました)

new HttpCookieCollection()のあなたのモックが正しいです。このコードは分離で動作します:

var request = new Mock<HttpRequestBase>(MockBehavior.Strict); 
request.SetupGet(x => x.ApplicationPath).Returns("/"); 
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute)); 
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection()); 

var response = new Mock<HttpResponseBase>(MockBehavior.Strict); 
response.Setup(x => x.ApplyAppPathModifier(Moq.It.IsAny<String>())).Returns((String url) => url); 
// response.SetupGet(x => x.Cookies).Returns(new HttpCookieCollection()); // This also failed to work 

var context = new Mock<HttpContextBase>(MockBehavior.Strict); 
context.SetupGet(x => x.Request).Returns(request.Object); 
context.SetupGet(x => x.Response).Returns(response.Object); 
context.SetupGet(x => x.Response.Cookies).Returns(new HttpCookieCollection()); // still can't call the Clear() method 


// Here clearing the cookies works just fine: 
var instance = context.Object; 
instance.Response.Cookies.Clear(); 

エラーはありませんが、他の場所です。あなたのコードからResponse.Cookies.Clear()という行をコメントアウトするとどうなりますか?それ以外のものはすべて正しく嘲笑されていますか?テストをデバッグすると、モックの残りの部分が期待どおりであることがわかりますか?それがあれば私は驚くだろう(しかし、私は前に驚いた...)。