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

.NET5运行集成测试时如何启动GraphQL服务器?

问题排查与修正方案

认知正误确认

你对WebApplicationFactory<Startup>的认知是正确的:它默认会完全复用主项目的Startup.cs配置,无需重复注册服务、重复写配置逻辑,额外添加的重复配置反而可能引发服务注册冲突。

现存问题与修正点

1. ApiWebApplicationFactory泛型继承错误

你定义的泛型类继承逻辑有误,导致无法正确加载传入的TStartup(主项目Startup类)配置:

// 错误写法
public class ApiWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
// 正确写法,继承对应泛型类
public class ApiWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class

2. 配置未注入WebHost

你构建的IConfiguration没有传递给WebHost,导致主项目中依赖配置的服务(比如DbContext、GraphQL配置)无法正确读取参数,需要在ConfigureWebHost中添加配置注入逻辑,同时确保测试项目的appsettings.json设置了「复制到输出目录:如果较新则复制」。

3. 重复注册GraphQL服务

ConfigureWebHost中重复添加的AddGraphQLServer配置和主项目Startup的注册逻辑冲突,直接删除这段配置即可。

4. GraphQL查询语法错误

你的查询语句中无参数的字段后多余添加了括号,会导致GraphQL服务器解析失败返回400 Bad Request,这是你当前报错的直接诱因,删除多余括号即可。

5. DbContext实例不统一

你单独初始化的CmsContext和WebHost DI容器中使用的CmsContext不是同一个实例,会导致测试操作的数据和接口实际使用的数据不一致,建议从工厂的服务容器中获取上下文实例。

修正后完整代码

ApiWebApplicationFactory.cs

public class ApiWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    public IConfigurationRoot Configuration { get; set; }

    public ApiWebApplicationFactory()
    {
        var configBuilder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
        Configuration = configBuilder.Build();
    }

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        // 注入自定义配置
        builder.UseConfiguration(Configuration);
    }

    protected override void ConfigureClient(HttpClient client)
    {
        base.ConfigureClient(client);
        client.BaseAddress = new Uri("https://localhost");
        client.Timeout = TimeSpan.FromMinutes(10);
    }
}

OneTimeSetUp逻辑

[OneTimeSetUp]
public void OneTimeSetUp()
{
    _factory = new ApiWebApplicationFactory<Startup>();
    _client = _factory.WithWebHostBuilder(builder =>
    {
        builder.ConfigureServices(services =>
        {
            // 替换为测试用缓存实现
            services.AddScoped<ICacheRepository, MockCache>();
        });
    }).CreateClient();

    // 从工厂DI容器获取DbContext,保证和接口使用的上下文一致
    using var scope = _factory.Services.CreateScope();
    _dbContext = scope.ServiceProvider.GetRequiredService<CmsContext>();
    _dbContext.Database.EnsureCreated();
}

测试方法逻辑

[Test]
public async Task Test()
{
    var graphQLHttpClient = new GraphQLHttpClient(
        new GraphQLHttpClientOptions { EndPoint = new Uri("https://localhost/graphql") },
        new NewtonsoftJsonSerializer(), 
        _client);
            
    var request = new GraphQLRequest
    {
        // 移除无参字段的多余括号
        Query = @"
            query GetCurrentSession {
                getCurrentSession {
                    id
                    name
                }
            }",
        OperationName = "GetCurrentSession"
    };

    var response = await graphQLHttpClient.SendQueryAsync<Session>(request);
    // 建议先断言无GraphQL执行错误,方便后续排查
    Assert.IsNull(response.Errors);
    // 后续业务断言
}

内容的提问来源于stack exchange,提问作者James654987

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:18:03