Xunit TestContainers 每个类只有一个服务器,每个测试都有新的数据库

问题描述 投票:0回答:1

我正在尝试启动一个 TestContainer 实例,为每个测试类创建 sql server。然后在每次测试之前创建并迁移一个新数据库,并在删除每个测试数据库之后。

TestContainer 夹具是使用 IAsyncLifetime 定义的,测试类也是如此,因为它们依赖于异步方法。

TestClass 使用 IClassFixture 为每个类定义单个 TestContainerFixture。这似乎工作正常,因为 TestContainerFixtures

InitializeAsync()
只被调用一次。

TestClass 还使用 IAsyncLifetime,并且 TestClasses

InitializeAsync()
在每次测试之前运行。这是可行的,但问题是我无法创建具有唯一名称的数据库,因为
Guid.NewGuid().ToString()
总是返回相同的结果。这是为什么?我是否缺少一些有关 xunit/.net-core 如何处理并行测试/线程的重要信息?

测试课是这样的:

public class TestClass: IClassFixture<TestContainerFixture>, IAsyncLifetime
{
    private readonly TestContainerFixture _testContainerFixture;

    public TestClass(TestContainerFixture fixture)
    {
        _testContainerFixture = fixture;
    }

    public async Task InitializeAsync()
    {
        // this guid will always be identical, that is the main problem
        var guid = Guid.NewGuid().ToString();

        var data = await _testContainerFixture.SetupDatabaseAsync(guid);
    }

    public async Task DisposeAsync()
    {
        await _testContainerFixture.DropDatabaseAsync();
    }
}

TestContainerFixture 定义如下:

public class TestContainerFixture : IAsyncLifetime
{
    private string _databaseName { get; set; } = String.Empty;

    private string _connectionString { get; set; } = String.Empty;

    private MsSqlContainer _databaseContainer { get; set; } = default!;

    public TestContainerFixture()
    {
    }

    public virtual async Task InitializeAsync()
    {
        _databaseContainer = new MsSqlBuilder()
                                .WithAutoRemove(autoRemove: true)
                                .WithExposedPort(54465)
                                .Build();

        await _databaseContainer.StartAsync();
    }

    public async Task<(IOptionsMonitor<Config>, IUnitOfWork)> SetupDatabaseAsync(string dbname)
    {
        _databaseName = dbname;
        // this commented out code also produces identical guids between tests
        //_databaseName = "Test" + Guid.NewGuid().ToString().Replace("-", "");
        await _databaseContainer.ExecScriptAsync($"create database [{dbname}]");
        _connectionString = _databaseContainer.GetConnectionString().Replace("Database=master", $"Database={dbname}");
    }

    public async Task DisposeAsync() => await _databaseContainer.StopAsync();
}
.net-core xunit testcontainers xunit.net
1个回答
0
投票

好吧,我明白了。也许当我说出这个问题时,突然想到了什么。解决方案是从 TestContainerFixture 属性中删除databaseName和connectionString,并将它们作为参数从TestClass IAsyncLifeTime一直传递。也许 TestClass 根本没有创建相同的 guid,也许我很困惑,因为 TestContainerFixture 只有一个实例并且私有属性没有更新。我使用 ITestOutputHelper 来解决这个问题。

有时必须再次测试一下,但现在可以了。

© www.soinside.com 2019 - 2024. All rights reserved.