自托管和使用xUnit Test时的IP地址

时间:2018-01-31 15:55:32

标签: c# asp.net-core integration-testing xunit

我的生产代码中有以下函数GetIpAddress。我有一个xUnit测试,它调用调用该函数的网站。正常运行时该函数可正常工作,但如果从xUnit测试运行,则RemoteIpAddress始终为null。下面是我的测试启动类,由主机构建器调用,测试功能用于发送请求。

internal static string GetIpAddress(HttpRequest request)
{
    try
    {
        if (request.HttpContext.Connection.RemoteIpAddress != null)
            return request.HttpContext.Connection.RemoteIpAddress.ToString();
    }
    catch (System.Exception ex)
    {
        DataLink.ProcessError(ex, "Error getting IP address");
        return "error";
    }

    return "unknown";
}


class TestStartup
{
    public TestStartup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ApmCore.Startup.Connection = Configuration.GetConnectionString("DefaultConnection");
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddMemoryCache();
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }

    public static HttpClient GetClient()
    {
        var server = new TestServer(new WebHostBuilder()
            .UseStartup<TestStartup>());
        var client = server.CreateClient();
        client.DefaultRequestHeaders
            .Accept
            .Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        return client;
    }

    public static HttpRequestMessage GetRequest(string args, string url)
    {
        return new HttpRequestMessage(HttpMethod.Get, new System.Uri(url))
        {
            Content = new StringContent(args, Encoding.UTF8, "application/json")
        };
    }
}

[Theory]
[MemberData(nameof(TestDataHandler.LogData), MemberType = typeof(TestDataHandler))]
public async Task TestGet(string args, bool expected)
{
    var response = await this._Client.SendAsync(TestStartup.GetRequest(args, "http://localhost/api/Log"));
    var data = await response.Content.ReadAsStringAsync();
    var result = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(data, new { success = false });
    Assert.Equal(result.success, expected);
}

1 个答案:

答案 0 :(得分:0)

这个问题似乎与Set dummy IP address in integration test with Asp.Net Core TestServer

重复

该问题的答案可用于解决此问题: https://stackoverflow.com/a/49244494/90287

<块引用>

您可以编写中间件来设置自定义 IP 地址,因为此属性 可写:

public class FakeRemoteIpAddressMiddleware
{
    private readonly RequestDelegate next;
    private readonly IPAddress fakeIpAddress = IPAddress.Parse("127.168.1.32");

    public FakeRemoteIpAddressMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        httpContext.Connection.RemoteIpAddress = fakeIpAddress;

        await this.next(httpContext);
    }
}

然后你可以像这样创建 StartupStub 类:

public class StartupStub : Startup
{
    public StartupStub(IConfiguration configuration) : base(configuration)
    {
    }

    public override void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseMiddleware<FakeRemoteIpAddressMiddleware>();
        base.Configure(app, env);
    }
}

并用它来创建一个 TestServer

new TestServer(new WebHostBuilder().UseStartup<StartupStub>());