0

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

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

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

4

1 回答 1

0

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

这篇 StackOverflow 帖子有一些很好的指导:Moq: unit testing a methoddependent HttpContext

更新:

您找到的 StackOverflow 帖子也是一个不错的帖子:How to set 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 模拟的所有花里胡哨。

于 2013-11-07T18:37:54.697 回答