如何使用Microsoft.AspNetCore.Mvc.Testing测试多ASP.NET Core服务连通性
问题结论
这个场景完全可以通过Microsoft.AspNetCore.Mvc.Testing实现,不需要引入Selenium这类工具,Selenium是面向前端交互的测试工具,和后端服务间连通性测试的场景不匹配。
核心实现思路
你遇到的问题本质是测试环境下Web2没有监听实际端口,Web1内部的HttpClient无法通过配置的真实地址访问到测试环境的Web2实例。而WebApplicationFactory创建的HttpClient默认走内存通信通道,不需要实际端口,你只需要把Web1内部调用Web2的HttpClient替换为Web2工厂生成的测试客户端即可。
具体改造步骤
1. 改造Web1的工厂类支持注入Web2测试客户端
假设你Web1原本是通过命名HttpClient注册的Web2调用客户端,Startup里的注册逻辑参考如下:
services.AddHttpClient("Web2Client", client => { client.BaseAddress = new Uri("https://localhost:156123/"); });
改造Web1ApplicationFactory,增加构造参数传入Web2的测试客户端,并且在服务注册阶段替换原有HttpClient的实现:
public class Web1ApplicationFactory : WebApplicationFactory<Startup1> { private readonly HttpClient _web2TestClient; // 新增构造函数接收Web2的测试客户端 public Web1ApplicationFactory(HttpClient web2TestClient) { _web2TestClient = web2TestClient; } protected override IHostBuilder CreateHostBuilder() => Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup1>(); }) // 替换Web1内部调用Web2的HttpClient逻辑 .ConfigureServices(services => { // 移除原有的Web2Client注册 var httpClientBuilder = services.AddHttpClient("Web2Client"); // 替换请求处理handler为Web2测试客户端的内存handler httpClientBuilder.AddHttpMessageHandler(() => new DelegatingHandler { InnerHandler = _web2TestClient.InnerHandler }); }); }
2. 调整测试基类初始化逻辑
确保先初始化Web2的工厂,再将其生成的客户端传入Web1工厂,替换内部调用逻辑,同时增加资源释放逻辑避免泄漏:
[Trait("Category", "E2E")] public abstract class E2ETestsBase : IDisposable { protected readonly HttpClient Client1; protected readonly HttpClient Client2; private readonly Web2ApplicationFactory _web2Factory; private readonly Web1ApplicationFactory _web1Factory; protected E2ETestsBase() { // 先初始化Web2工厂,拿到内存通信的测试客户端 _web2Factory = new Web2ApplicationFactory(); Client2 = _web2Factory.CreateClient(); // 把Web2的测试客户端传入Web1工厂,替换内部调用逻辑 _web1Factory = new Web1ApplicationFactory(Client2); Client1 = _web1Factory.CreateClient(); } public void Dispose() { _web1Factory.Dispose(); _web2Factory.Dispose(); Client1.Dispose(); Client2.Dispose(); } }
补充说明
- 调整完成后你原有测试用例的代码不需要做任何修改,Web1内部所有发往Web2的请求都会直接通过内存通道送达测试环境的Web2实例,不需要经过真实网络,执行效率更高也不会有端口冲突问题。
- 如果你用的是Typed HttpClient(比如自定义了
IWeb2ApiClient封装调用逻辑),只需要调整替换逻辑,把Typed Client的内部请求处理handler替换为Web2测试客户端的handler即可。
内容的提问来源于stack exchange,提问作者Peter Pollen
相关产品推荐
相关产品推荐

