11

MOQ は初めてですが、単体テストに NUnit を使用しています。

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

Response.Cookies.Clear();

これまでに遭遇した他のすべてのもので機能するコントローラーコンテキストをモックする次の拡張メソッドがあります (このフォーラムの善良な人々に非常に感謝します)。

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

上記のように、Cookie コレクションの「get」をモックしようとしましたが、役に立ちません。

また、実際の Clear() メソッドは仮想メソッドではないため、モックできません。

明らかに、Cookie がクリアされていることをテストしたくありません。テストで無視できるようにしたいだけです。

ありがとう、

グレッグ

4

3 に答える 3

19

これは、cookies.Clear() を実行するときに機能します

            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);
于 2013-08-07T11:10:44.070 に答える
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()か? 他のすべてが正しく嘲笑されていますか?テストをデバッグすると、モックの残りの部分が期待どおりであることがわかりますか? だったらビックリします(でも、以前はビックリしたことがあるのですが…)。

于 2013-08-07T11:03:54.313 に答える