如何为SignalR编写集成测试?无法连接真实Hub实例问题
问题分析与解决步骤
核心问题
你的测试代码没有复用WebApplicationFactory绑定的测试服务器资源,而是新建了独立的HttpClientHandler,导致SignalR连接无法指向测试运行的真实Hub实例。以下是具体修复步骤:
1. 复用测试服务器的消息处理器
WebApplicationFactory的Server.CreateHandler()方法会返回与测试服务器绑定的处理器,必须用它来构建SignalR连接,才能让客户端和测试中的Hub建立通信。
2. 确认SignalR路由配置
确保在Program.cs(或Startup.cs)中正确注册Hub路由,这是连接能找到Hub端点的前提:
// Program.cs 中的配置代码 app.MapHub<AuctionHub>("/auction-hub");
3. 修正后的完整测试代码
[Fact] public async Task Should_ConnectToAuctionHubAndReceiveMessage() { using var factory = new WebApplicationFactory<Program>(); // 获取测试服务器绑定的消息处理器 var serverHandler = factory.Server.CreateHandler(); // 构建Hub连接 var connection = new HubConnectionBuilder() .WithUrl(factory.ClientOptions.BaseAddress + "/auction-hub", options => { options.HttpMessageHandlerFactory = _ => serverHandler; // 若测试环境启用HTTPS,关闭证书验证(按需添加) if (factory.ClientOptions.BaseAddress.Scheme == "https") { var handler = (HttpClientHandler)serverHandler; handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; } }) .Build(); // 监听Hub发送的UserWasOutbid事件,验证连接后的消息推送 var messageReceived = new TaskCompletionSource<string>(); connection.On<string>("UserWasOutbid", msg => messageReceived.SetResult(msg)); try { await connection.StartAsync(); // 等待消息或超时,验证是否收到OnConnectedAsync发送的消息 var completedTask = await Task.WhenAny(messageReceived.Task, Task.Delay(2000)); Assert.Same(completedTask, messageReceived.Task); Assert.StartsWith("Hey ", messageReceived.Task.Result); } finally { await connection.StopAsync(); } }
4. 可选:模拟用户身份(针对需要认证的Hub)
如果你的Hub依赖Context.UserIdentifier,可以在测试中添加认证头:
var connection = new HubConnectionBuilder() .WithUrl(factory.ClientOptions.BaseAddress + "/auction-hub", options => { options.HttpMessageHandlerFactory = _ => serverHandler; // 添加模拟认证头 options.Headers.Add("Authorization", "Bearer test-jwt-token"); }) .Build();
内容的提问来源于stack exchange,提问作者Pentium3k
相关产品推荐
相关产品推荐

