Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 在与Asp.Net Core TestServer的集成测试中设置虚拟IP地址_Asp.net Core_Integration Testing_Asp.net Core Webapi - Fatal编程技术网

Asp.net core 在与Asp.Net Core TestServer的集成测试中设置虚拟IP地址

Asp.net core 在与Asp.Net Core TestServer的集成测试中设置虚拟IP地址,asp.net-core,integration-testing,asp.net-core-webapi,Asp.net Core,Integration Testing,Asp.net Core Webapi,我有一个C#Asp.Net Core(1.x)项目,它实现了一个web REST API及其相关的集成测试项目,在任何测试之前,都有一个类似以下的设置: /。。。 IWebHostBuilder webHostBuilder=GetWebHostBuildersMilarToRealOne() .UseStartup(); TestServer服务器=新的TestServer(webHostBuilder); server.BaseAddress=新Uri(“http://localhost:5

我有一个C#Asp.Net Core(1.x)项目,它实现了一个web REST API及其相关的集成测试项目,在任何测试之前,都有一个类似以下的设置:

/。。。
IWebHostBuilder webHostBuilder=GetWebHostBuildersMilarToRealOne()
.UseStartup();
TestServer服务器=新的TestServer(webHostBuilder);
server.BaseAddress=新Uri(“http://localhost:5000");
HttpClient=server.CreateClient();
// ...
在测试期间,
客户端
用于向web API(测试中的系统)发送HTTP请求并检索响应

在实际的测试系统中,有一些组件从每个请求中提取发送方IP地址,如下所示:

HttpContext HttpContext=ReceiveHttpContextDuringAuthentication();
//为简洁起见,省略了边缘情况
字符串remoteIpAddress=httpContext?.Connection?.remoteIpAddress?.ToString()
现在,在集成测试期间,这段代码找不到IP地址,因为
RemoteIpAddress
始终为空


有没有办法从测试代码中将其设置为某个已知值?我一直在这里搜索,但没有找到类似的东西。TA

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

公共类fakeremoteipAddress中间件
{
私有只读请求委托下一步;
private readonly IPAddress fakeIpAddress=IPAddress.Parse(“127.168.1.32”);
公共FakeRemoteIpAddressMiddleware(RequestDelegate下一步)
{
this.next=next;
}
公共异步任务调用(HttpContext HttpContext)
{
httpContext.Connection.RemoteIpAddress=fakeIpAddress;
等待这个。下一步(httpContext);
}
}
然后您可以像这样创建
StartupStub
类:

公共类StartupStub:启动
{
公共StartupStub(IConfiguration配置):基本(配置)
{
}
公共覆盖无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
app.UseMiddleware();
配置(应用程序、环境);
}
}
并使用它创建一个
TestServer

newtestserver(newWebHostBuilder().UseStartup());
根据此答案

还可以从ConfigureServices配置中间件,这允许您创建自定义WebApplicationFactory,而无需StartupStub类:

公共类CustomWebApplicationFactory:WebApplicationFactory
{
受保护的覆盖IWebHostBuilder CreateWebHostBuilder()
{
返回网络主机
.CreateDefaultBuilder(新字符串[0])
.ConfigureServices(服务=>
{
services.AddSingleton();
});
}
}
公共类CustomStartupFilter:IStartupFilter
{
公共操作配置(下一步操作)
{
返回应用=>
{
app.UseMiddleware();
下一步(应用程序);
};
}
}

使用WebHost.CreateDefaultBuilder可能会弄乱应用程序配置

除非绝对必要,否则不需要仅仅为了适应测试而更改产品代码

添加自己的中间件而不重写启动类方法的最简单方法是通过
IStartupFilter添加中间件‍如Elliott的回答所示

但是不要使用
WebHost.CreateDefaultBuilder
,只需使用

base.CreateWebHostBuilder().ConfigureServices...

    public class CustomWAF : WebApplicationFactory<Startup>
    {
        protected override IWebHostBuilder CreateWebHostBuilder()
        {
            return base.CreateWebHostBuilder().ConfigureServices(services =>
            {
                services.AddSingleton<IStartupFilter, CustomStartupFilter>();
            });
        }
    }
base.CreateWebHostBuilder().ConfigureServices。。。
公共类CustomWAF:WebApplicationFactory
{
受保护的覆盖IWebHostBuilder CreateWebHostBuilder()
{
返回base.CreateWebHostBuilder().ConfigureServices(服务=>
{
services.AddSingleton();
});
}
}

Show
ReceiveHttpContextDuringAuthentication()
这只是一个虚构的函数,用来表示正在发生的事情。在实际代码中,IP地址是在身份验证框架()提供的扩展点内提取的。该框架将当前请求
HttpContext
作为一个输入传递给扩展点。看起来这可能是缺少的部分。例如,谢谢你,我会尝试一下,但是是的,它看起来很有前途。你也使用了dotnet core 2.x吗?看起来“Configure”在2.x中无法再被覆盖。@Ralf您是否在
启动
类中将
配置
标记为
虚拟
?@PavelAgarkov您的解决方案是在中间件中对IP进行硬编码,这意味着所有集成测试都将使用相同的IP地址。是否还有一种方法可以声明每个测试用例单独使用的IP(例如,在创建HttpRequest时),以便可以考虑各种测试场景(具有各种IP地址)?@Dario,当然,您可以使用ConfigureTestServices注册一些服务,这些服务将注入FakeremoteiPadressMiddleware并用于获取当前ip地址。通过这种方式,您可以在使用客户端之前指定不同的ip地址。感谢您花时间回答这个问题,即使它比较旧。现在我离一个类似的项目还很远,让我们看看新项目会发生什么。非常感谢你的回答。如果不继承一个新的启动类(有其自身的缺点),直接通过
WebApplicationFactory
配置其他中间件是不可能的,但是这种方法非常有效。对于使用.NET 5或Core 3.x的人来说,.ConfigureServices调用应该放在
protected override IHost CreateHost中(IHostBuilder)
而不是
CreateWebHostBuilder