如何在请求中设置用户主机地址

时间:2013-11-07 18:22:30

标签: asp.net unit-testing

我发现此代码用于执行单元测试的模拟请求。我正在尝试设置userhostaddress,但我不清楚如何使用此代码中概述的相同方法来实现这一点。我认为它必须通过反射来完成,因为我发现不允许设置标题。我有什么想法可以实现这个目标吗?

public static HttpContext FakeHttpContext()
        {
            var httpRequest = new HttpRequest("", "http://fakurl/", "");
            var stringWriter = new StringWriter();
            var httpResponse = new HttpResponse(stringWriter);
            var httpContext = new HttpContext(httpRequest, httpResponse);

            var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                                    new HttpStaticObjectsCollection(), 10, true,
                                                    HttpCookieMode.AutoDetect,
                                                    SessionStateMode.InProc, false);

            httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null, CallingConventions.Standard,
                                        new[] { typeof(HttpSessionStateContainer) },
                                        null)
                                .Invoke(new object[] { sessionContainer });

            httpContext.Request.Headers["REMOTE_ADDR"] = "XXX.XXX.XXX.XXX"; // not allowed
            return httpContext;
        }

我也试过这个模拟库:

https://gist.github.com/rally25rs/1578697

用户主机地址仍然是只读的。

1 个答案:

答案 0 :(得分:0)

我发现的最佳方法是使用某种实现IContextService接口的ContextService。这个类/接口对可以执行您需要的任何操作。重点是,如果您在单元测试中使用模拟框架,如MOQ,那么您可以连接模拟上下文服务以返回特定的IP地址。

这篇StackOverflow帖子有一些很好的指示:Moq: unit testing a method relying on HttpContext

更新

您找到的StackOverflow帖子也很好:How to set the IP (UserHostAddress) on a "mocked' BaseHttpContext?

我发现通常我只需要上下文/请求/响应对象中的一些属性,所以我经常使用自己的小变体:

public class ContextService : IContextService
{
    public string GetUserHostAddress()
    {
        return HttpContext.Current.Request.UserHostAddress;
    }
}
public interface IContextService
{
    string GetUserHostAddress();
}

使用该类/接口组合,我可以使用Moq连接假服务:

var contextMock = new Moq.Mock<IContextService>();
contextMock.Setup(c => c.GetUserHostAddress()).Returns("127.0.0.1");

现在,每当我拨打contextMock.GetUserHostAddress()时,我都会收到“127.0.0.1”。滚动你自己可以是一个很好的学习经验,特别是如果你不需要一个完整的(或尽可能完整的)HttpContext模拟的所有花里胡哨。