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

.NET 7 REST API集成测试:Testcontainers 3.0.0配置SQL Server遇阻

解决方案:.NET 7 REST API集成测试中使用SQL Server Testcontainers(3.0.0版本)

1. 安装正确的NuGet包

Testcontainers 3.x版本采用模块化设计,需安装SQL Server专用包替代基础包:

Install-Package Testcontainers.MsSql -Version 3.0.0

或通过.NET CLI:

dotnet add package Testcontainers.MsSql --version 3.0.0

2. 正确构建SQL Server容器(替代废弃的ContainerBuilder)

3.x版本中直接使用MsSqlBuilder封装SQL Server容器的所有必要配置,无需手动拼接环境变量和等待策略:

using Testcontainers.MsSql;
using Microsoft.EntityFrameworkCore;

public class ApiIntegrationTests : IAsyncLifetime
{
    private readonly MsSqlContainer _dbContainer;
    private AppDbContext _dbContext;

    public ApiIntegrationTests()
    {
        _dbContainer = new MsSqlBuilder()
            .WithPassword("MyStrongPass123!") // 需符合SQL Server密码规则:8位以上,含大小写、数字、特殊字符
            .WithDatabase("LocalTestDb") // 容器启动时自动创建该数据库
            .Build();
    }

    public async Task InitializeAsync()
    {
        // 启动容器并等待服务就绪
        await _dbContainer.StartAsync();

        // 配置EF Core上下文,使用容器自动生成的连接字符串
        var dbOptions = new DbContextOptionsBuilder<AppDbContext>()
            .UseSqlServer(_dbContainer.GetConnectionString())
            .Options;

        _dbContext = new AppDbContext(dbOptions);

        // 执行EF迁移,自动创建表结构
        await _dbContext.Database.MigrateAsync();
    }

    public async Task DisposeAsync()
    {
        await _dbContext.DisposeAsync();
        await _dbContainer.StopAsync();
        await _dbContainer.DisposeAsync();
    }

    // 集成测试用例示例
    [Fact]
    public async Task Post_Entity_ReturnsCreatedEntity()
    {
        // 测试逻辑:先往数据库插测试数据,再调用API验证结果
        var testItem = new TestEntity { Name = "Test Item" };
        _dbContext.TestEntities.Add(testItem);
        await _dbContext.SaveChangesAsync();

        // 初始化API客户端并调用接口,此处省略客户端创建代码
        // var response = await _apiClient.PostAsync("/api/items", testItem);
        // Assert.Equal(HttpStatusCode.Created, response.StatusCode);
    }
}

3. 你之前代码的报错原因及修复

  • 端口冲突:手动指定WithPortBinding(49401, 1433)会占用固定端口,若端口已被其他程序占用则触发Conflict错误。Testcontainers默认自动分配随机可用端口,无需手动绑定。
  • 容器启动失败:SA密码MyStrongPassword不符合SQL Server复杂度要求,导致容器启动失败,进而触发"容器未运行"错误。需调整密码包含大小写、数字和特殊字符。
  • 等待策略错误:手动配置的UntilCommandIsCompleted命令引号格式错误,且缺少SQL Server服务就绪的完整等待逻辑,MsSqlBuilder已内置完善的等待机制。

4. 数据库/表创建说明

无需手动创建:

  • 通过MsSqlBuilder.WithDatabase()可指定容器启动时自动创建目标数据库。
  • 借助EF Core的Database.MigrateAsync(),会自动应用所有迁移脚本生成表结构;若未使用迁移,可改用Database.EnsureCreatedAsync()(迁移更适合长期维护场景)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:05:19