You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:35:01