【问题标题】:Mocking and HttpContextBase.get_User()模拟和 HttpContextBase.get_User()
【发布时间】:2009-03-24 15:02:23
【问题描述】:

我想模拟 HttpContext 的 User 属性。 我正在使用 Scott Hanselmans MVCHelper 类和 RhinoMocks。

我有一个包含代码的单元测试,如下所示:

...

MockIdentity fakeId = new MockIdentity("TEST_USER", "Windows", true);
MockPrincipal fakeUser = new MockPrincipal(null, fakeId);

using (mocks.Record())
{
    Expect.Call(fakeHttpContext.User).Return(fakeUser);
}

...

我的 MockIdentity 和 MockPrincipal 类分别是符合 IIdentity 和 IPrincipal 的模拟。

运行单元测试时出现错误报告:

System.NotImplementedException: 方法或操作不是 实施的。在 System.Web.HttpContextBase.get_User()

当我尝试为 User 属性设置期望值时会发生这种情况。

我知道 httpContextBase 有一个未实现的 getter 和 setter,但我认为 Rhino 在模拟时会处理这个问题。

这是否意味着我必须从 HttpContextbase 派生并覆盖我的模拟对象的属性。看起来很奇怪。

其他用户也遇到过此问题,并在此处报告: http://www.mail-archive.com/rhinomocks@googlegroups.com/msg00546.html

【问题讨论】:

    标签: c# asp.net-mvc rhino-mocks


    【解决方案1】:

    我遇到了几乎同样的问题,然后搬到了起订量。

    这是我在应用中使用的自定义助手:

    public static class MvcMockHelpers
        {
            public static HttpContextBase FakeHttpContext()
            {
    
                var context = new Mock<HttpContextBase>();
                var request = new Mock<HttpRequestBase>();
                var response = new Mock<HttpResponseBase>();
                var session = new Mock<HttpSessionStateBase>();
                var server = new Mock<HttpServerUtilityBase>();
    
                context.Expect(ctx => ctx.Request).Returns(request.Object);
                context.Expect(ctx => ctx.Response).Returns(response.Object);
                context.Expect(ctx => ctx.Session).Returns(session.Object);
                context.Expect(ctx => ctx.Server).Returns(server.Object);
    
    
                var form = new NameValueCollection();
                var querystring = new NameValueCollection();
                var cookies = new HttpCookieCollection();
                var user = new GenericPrincipal(new GenericIdentity("testuser"), new string[] { "Administrator" });
    
                request.Expect(r => r.Cookies).Returns(cookies);
                request.Expect(r => r.Form).Returns(form);
                request.Expect(q => q.QueryString).Returns(querystring);
    
                response.Expect(r => r.Cookies).Returns(cookies);
    
                context.Expect(u => u.User).Returns(user);
    
    
    
                return context.Object;
            }
    
            public static HttpContextBase FakeHttpContext(string url)
            {
                HttpContextBase context = FakeHttpContext();
                context.Request.SetupRequestUrl(url);
    
                return context;
    
            }
    
    
            public static void SetFakeControllerContext(this Controller controller)
            {
                var httpContext = FakeHttpContext();
                ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
                controller.ControllerContext = context;
            }
    
            public static void SetFakeControllerContext(this Controller controller, RouteData routeData)
            {
                SetFakeControllerContext(controller, new Dictionary<string, string>(), new HttpCookieCollection(), routeData);
            }
    
            public static void SetFakeControllerContext(this Controller controller, HttpCookieCollection requestCookies)
            {
                SetFakeControllerContext(controller,new Dictionary<string,string>(),requestCookies, new RouteData());
            }
    
            public static void SetFakeControllerContext(this Controller controller, Dictionary<string, string> formValues)
            {
                SetFakeControllerContext(controller, formValues, new HttpCookieCollection(), new RouteData());
            }
    
            public static void SetFakeControllerContext(this Controller controller,
                Dictionary<string, string> formValues,
                HttpCookieCollection requestCookies,
                RouteData routeData)
            {
                var httpContext = FakeHttpContext();
    
                foreach (string key in formValues.Keys)
                {
                    httpContext.Request.Form.Add(key, formValues[key]);
    
                }
                foreach (string key in requestCookies.Keys)
                {
                    httpContext.Request.Cookies.Add(requestCookies[key]);
    
                }
                ControllerContext context = new ControllerContext(new RequestContext(httpContext, routeData), controller);
                controller.ControllerContext = context;
            }
    
            public static void SetFakeControllerContextWithLogin(this Controller controller, string userName,
                string password,
                string returnUrl)
            {
    
                var httpContext = FakeHttpContext();
    
    
                httpContext.Request.Form.Add("username", userName);
                httpContext.Request.Form.Add("password", password);
                httpContext.Request.QueryString.Add("ReturnUrl", returnUrl);
    
                ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
                controller.ControllerContext = context;
            }
    
    
            static string GetUrlFileName(string url)
            {
                if (url.Contains("?"))
                    return url.Substring(0, url.IndexOf("?"));
                else
                    return url;
            }
    
            static NameValueCollection GetQueryStringParameters(string url)
            {
                if (url.Contains("?"))
                {
                    NameValueCollection parameters = new NameValueCollection();
    
                    string[] parts = url.Split("?".ToCharArray());
                    string[] keys = parts[1].Split("&".ToCharArray());
    
                    foreach (string key in keys)
                    {
                        string[] part = key.Split("=".ToCharArray());
                        parameters.Add(part[0], part[1]);
                    }
    
                    return parameters;
                }
                else
                {
                    return null;
                }
            }
    
            public static void SetHttpMethodResult(this HttpRequestBase request, string httpMethod)
            {
                Mock.Get(request)
                    .Expect(req => req.HttpMethod)
                    .Returns(httpMethod);
            }
    
            public static void SetupRequestUrl(this HttpRequestBase request, string url)
            {
                if (url == null)
                    throw new ArgumentNullException("url");
    
                if (!url.StartsWith("~/"))
                    throw new ArgumentException("Sorry, we expect a virtual url starting with \"~/\".");
    
                var mock = Mock.Get(request);
    
                mock.Expect(req => req.QueryString)
                    .Returns(GetQueryStringParameters(url));
                mock.Expect(req => req.AppRelativeCurrentExecutionFilePath)
                    .Returns(GetUrlFileName(url));
                mock.Expect(req => req.PathInfo)
                    .Returns(string.Empty);
            }
    

    【讨论】:

    • 但他也提供了答案。
    【解决方案2】:

    要模拟用户属性,您可以这样做:

    var httpContext = MockRepository.GenerateStub<HttpContextBase>();
    httpContext.Stub(x=>x.User).Return(yourFakePrincipalHere);
    
    var controllerContext = new ControllerContext(httpContext, ....);
    
    var controller = new HomeController();
    controller.ControllerContext = controllerContext;
    

    (这使用新的 RM 3.5 api,如果您正在使用记录/重放,那么:

    using(mocks.Record)
    {
       _httpContext = _mocks.DynamicMock<HttpContextBase>();
       SetupResult.For(_httpContext.User).Return(...);
    }
    
    using(mocks.PlayBack())
    {
       ....
    }
    

    【讨论】:

    • 布莱恩特本。干杯。我认为我对 Stubs 和 Mocks 的理解需要一些“梳理”。我确实遇到了问题:httpContext.Stub(x=>x.User).Return(yourFakePrincipalHere);但替换为:httpContext.User -= [fakeUser];效果很好。
    【解决方案3】:

    [免责声明:我在Typemock工作]

    我知道这不是您所要求的,但查看上面的答案,我必须展示另一种方法来满足您的需求 - 使用 Isolator

    var fakeId = Isolate.Fake.Instance<IIdentity>();
    Isolate.WhenCalled(() => fakeId.AuthenticationType).WillReturn("Windows");
    Isolate.WhenCalled(() => fakeId.Name).WillReturn("TEST_USER");
    Isolate.WhenCalled(() => fakeId.IsAuthenticated).WillReturn(true);
    
    var fakePrincipal = Isolate.Fake.Instance<IPrincipal>();
    Isolate.WhenCalled(() => fakePrincipal.Identity).WillReturn(fakeId);
    
    var fakeContext = Isolate.Fake.Instance<HttpContext>();
    Isolate.WhenCalled(() => fakeContext.User).WillReturn(fakePrincipal);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多