Интеграционные тесты сбои, потому что «следующие параметры конструктора не имели данных соответствия приспособления»C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Интеграционные тесты сбои, потому что «следующие параметры конструктора не имели данных соответствия приспособления»

Сообщение Anonymous »

Я пытаюсь создать интеграционные тесты в .NET 9 C#, используя xUnit и TestContainers. Однако всякий раз, когда я запускаю тесты, для каждого тестового класса создается новый контейнер базы данных. Я хочу инициализировать только один контейнер базы данных для всех тестовых классов.
Чтобы решить эту проблему, я попробовал использовать коллекции, поэтому одна коллекция инициализирует одну базу данных для всех объявленных в ней тестов. Однако я получаю следующую ошибку:

Код: Выделить всё

The following constructor parameters did not have matching fixture data: IntegrationTestWebAppFactory factory
< /code>
my code:
databasefixture < /p>
Я использую Respawn для сброса базы данных после каждого теста, а затем воссоздаю сценарии тестирования, используя семенные данные Из файлов SQL для случаев, которые требуют ранее существовавших данных.
using System.Data.Common;

using Microsoft.Data.SqlClient;

using Respawn;

using Testcontainers.MsSql;

using Tests.Integration.Persistence.Models;

namespace Tests.Integration.Abstractions.Fixtures;

public class DatabaseFixture : IAsyncLifetime, IDisposable
{
private const string _testContainerPassword = "MyPassword";

private DbConnection _dbConnection = default!;
private Respawner _respawner = default!;
private Dictionary _isclaRespawners = default!;

private readonly MsSqlContainer _container = new MsSqlBuilder()
.WithImage("mcr.microsoft.com/mssql/server:2022-CU16-ubuntu-22.04")
.WithPassword(_testContainerPassword)
.Build();

public string ConnectionString => _container.GetConnectionString();

public async Task ResetDataBaseAsync()
{
await _respawner.ResetAsync(ConnectionString);
foreach (var i in _isclaRespawners)
{
await i.Value.ResetAsync(i.Key);
}
await SeedDatabase();
}

private async Task InitializeRespawner()
{
_dbConnection = new SqlConnection(ConnectionString);
await _dbConnection.OpenAsync();
var lstIscalaConnections = await SeedDatabase();
_isclaRespawners = new Dictionary();

_respawner = await Respawner.CreateAsync(_dbConnection, new RespawnerOptions
{
DbAdapter = DbAdapter.SqlServer,
SchemasToInclude = new[] {
"dbo",
},
WithReseed = true
});

foreach (var i in lstIscalaConnections)
{

if (!String.IsNullOrWhiteSpace(i.ServidorErp))
{
var iscalaConnectionString = ConnectionString
.Replace("MyDb", i.BaseErp);

if (!_isclaRespawners.TryGetValue(iscalaConnectionString, out var existingRespawner))
{
var respawner = await Respawner.CreateAsync(iscalaConnectionString, new RespawnerOptions
{
DbAdapter = DbAdapter.SqlServer,
SchemasToInclude = new[] {
"dbo",
},
WithReseed = true
});

_isclaRespawners.Add(iscalaConnectionString, respawner);
}
}

if (!String.IsNullOrWhiteSpace(i.BaseErpfd))
{
var iscalaFDConnectionString = ConnectionString
.Replace("MyDb", i.BaseErpfd);

if (!_isclaRespawners.TryGetValue(iscalaFDConnectionString, out var existingRespawner))
{
var respawnerFD = await Respawner.CreateAsync(iscalaFDConnectionString, new RespawnerOptions
{
DbAdapter = DbAdapter.SqlServer,
SchemasToInclude = new[] {
"dbo",
},
WithReseed = true
});

_isclaRespawners.Add(iscalaFDConnectionString, respawnerFD);
}
}
}
}

protected async Task  SeedDatabase()
{
using (var command = _dbConnection.CreateCommand())
{
string baseSeedDir = "../../../Persistence/Seeds";
// Seed MyDb Empresas
string SeedSisautoScript = await File.ReadAllTextAsync($"{baseSeedDir}/SeedMyDb.sql");
command.CommandText = SeedSisautoScript;
await command.ExecuteScalarAsync();

// Initialize iScalaDb
if (!await IsIscalaDBInitialized(command))
{
string InitializeIscalaDbScript = await File.ReadAllTextAsync($"{baseSeedDir}/InitializeIscala.sql");
command.CommandText = InitializeIscalaDbScript;
await command.ExecuteScalarAsync();
}

// Seed iScalaDb
string SeedIscalaDbScript = await File.ReadAllTextAsync($"{baseSeedDir}/SeedIscala.sql");
command.CommandText = SeedIscalaDbScript;
await command.ExecuteScalarAsync();

var lstIscalaConnections = await GetCompanysInfo(command);

return lstIscalaConnections;
}
}

private static async Task IsIscalaDBInitialized(DbCommand command)
{
command.CommandText = "SELECT COUNT(*) FROM sys.databases";
var dbReader = await command.ExecuteReaderAsync();
if (await dbReader.ReadAsync())
{
var contagem = (int)dbReader[0];
await dbReader.CloseAsync();
if (contagem > 5)
{
return true;
}
}
return false;
}

private static async Task  GetCompanysInfo(DbCommand dbSisautoCommand)
{
var lstConnections = new List();
dbSisautoCommand.CommandText = @"SELECT
e.serverErp
,e.baseERP
,HasFD = CASE e.hasFD WHEN 1 THEN '1' ELSE '0' END
,e.serverErpFD
,e.baseERPFD
FROM
Company e
GROUP BY
e.serverErp
,e.baseERP
,e.temFD
,e.serverErpFD
,e.baseERPFD ";
var dbReader = await dbSisautoCommand.ExecuteReaderAsync();
while (await dbReader.ReadAsync())
{

var obj = new IscalaConnections
{
ServidorErp = dbReader["serverErp"].ToString()!,
BaseErp = dbReader["baseERP"].ToString()!,
withFatDir = dbReader["HasFD"].ToString() == "1",
ServidorErpfd = dbReader["serverErpFD"].ToString(),
BaseErpfd = dbReader["BaseErpfd"].ToString(),
};

lstConnections.Add(obj);
}
await dbReader.CloseAsync();

return lstConnections;
}

public async Task InitializeAsync()
{
await _container.StartAsync();
await InitializeRespawner();
}

public async Task DisposeAsync()
{
await _container.DisposeAsync();
await _dbConnection.DisposeAsync();
}

public void Dispose() {}
}
SharadTestDbCollection

Код: Выделить всё

using Tests.Integration.Abstractions.Fixtures;

namespace Integration.Tests.Abstractions;

[CollectionDefinition(nameof(SharadTestDbCollection))]
public class SharadTestDbCollection : ICollectionFixture;
IntegrationTestWebAppFactory

Код: Выделить всё

using Infra.Persistence.DBIscala;
using Infra.Persistence.DbSisauto;
using Infra.Services.Classes;

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;

using Tests.Integration.Abstractions.Fixtures;

namespace Integration.Tests.Abstractions;

[Collection(nameof(SharadTestDbCollection))]
public class IntegrationTestWebAppFactory : WebApplicationFactory, IAsyncLifetime
{
private readonly DatabaseFixture _dbFixture;
public Func ResetDataBaseAsync;
private string _connectionString = null!;
public HttpClient HttpClient {get; private set;} = default!;

public IntegrationTestWebAppFactory(DatabaseFixture dbFixture)
{
_dbFixture = dbFixture;
ResetDataBaseAsync = dbFixture.ResetDataBaseAsync;
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
_connectionString = _dbFixture.ConnectionString;
_connectionString = _connectionString.Replace("master", "myDB");
builder.ConfigureTestServices(services => {
// Remove serviços
services.RemoveAll(typeof(DbContextOptions));
services.RemoveAll(typeof(DbContextOptions));
services.RemoveAll(typeof(IOptions));

services.AddOptions();
services.AddDbContext(opt => {
opt.UseSqlServer(_connectionString);
});
services.AddDbContext();

var iscalaOptions = new IscalaDbOptions
{

ConnectionString = _connectionString.Replace("myDB", "{BaseERP}"),
};
services.AddSingleton(_ =>  Options.Create(iscalaOptions));
});
}

public Task InitializeAsync()
{
HttpClient = CreateClient();

return Task.CompletedTask;
}

public Task DisposeAsync() => Task.CompletedTask;

}
sharadtestcollection

Код: Выделить всё

namespace Integration.Tests.Abstractions;

[CollectionDefinition(nameof(SharadTestCollection))]
public class SharadTestCollection : ICollectionFixture;
BaseIntegrationTest

Код: Выделить всё

using MediatR;
using Microsoft.Extensions.DependencyInjection;

namespace Integration.Tests.Abstractions;

[CollectionDefinition(nameof(SharadTestCollection))]
public class BaseIntegrationTest : IAsyncLifetime
{
protected readonly IServiceScope _scope;
private readonly Func _resetDatabase;
protected readonly ISender Sender;
protected readonly HttpClient _client;

protected BaseIntegrationTest(IntegrationTestWebAppFactory factory)
{
_scope = factory.Services.CreateScope();
Sender = _scope.ServiceProvider.GetRequiredService();
_client = factory.HttpClient;
_resetDatabase = factory.ResetDataBaseAsync;
}

public virtual Task InitializeAsync() => Task.CompletedTask;

public virtual async Task DisposeAsync() {
await _resetDatabase();
_scope.Dispose();
_client.Dispose();
}
}
Тесты поставщиков

Код: Выделить всё

using System;
using System.Net.Http.Json;

using Domain.EmpresaDomain;
using Domain.FornecedorDomain;

using Integration.Tests.Abstractions;

namespace Tests.Integration.Tests.Fornecedor;

public class SupplierTests : BaseIntegrationTest
{
public SupplierTests(IntegrationTestWebAppFactory factory) : base(factory)
{
}

[Fact]
public async Task ShuldReturn10()
{
// Arrange
_client.DefaultRequestHeaders
.Add("X-TenantId", "1");

// Act
var suppliers = await _client.GetFromJsonAsync("/api/supplier");

// Assert
Assert.NotNull(fornecedores);
Assert.IsType(fornecedores);
var qtdeSupplier = 10;
Assert.Equal(suppliers.Count, qtdeSupplier);
}
}
Раньше конфигурация базы данных находилась в IntegrationTestWebAppFactory, но поскольку создавалось несколько баз данных, я попытался переместить ее в другое место. Однако мне не удалось заставить его работать с приведенным выше кодом.
Может ли кто-нибудь помочь мне определить, что я делаю неправильно и как это исправить?

Подробнее здесь: https://stackoverflow.com/questions/793 ... rs-did-not
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»