Prodest.IntegrationTests.Containers
6.0.10
dotnet add package Prodest.IntegrationTests.Containers --version 6.0.10
NuGet\Install-Package Prodest.IntegrationTests.Containers -Version 6.0.10
<PackageReference Include="Prodest.IntegrationTests.Containers" Version="6.0.10" />
paket add Prodest.IntegrationTests.Containers --version 6.0.10
#r "nuget: Prodest.IntegrationTests.Containers, 6.0.10"
// Install Prodest.IntegrationTests.Containers as a Cake Addin
#addin nuget:?package=Prodest.IntegrationTests.Containers&version=6.0.10
// Install Prodest.IntegrationTests.Containers as a Cake Tool
#tool nuget:?package=Prodest.IntegrationTests.Containers&version=6.0.10
Prodest.IntegrationTests.Containers
Sobre
Biblioteca para utilizar containers durante a execução de testes de integração, onde todo o ciclo de vida da api e containers é atrelado ao teste em execução, onde tudo é parado e descartado após a sua conclusão.
Como usar?
- Faça a sua classe de testes herdar a classe BaseTests:
public sealed class AcmeTests : BaseTests
E Implemente um construtor na classe derivada que recebe um ITestOutputHelper
e passa
para a classe base. Esse helper é Xunit e ajuda a captura de output de textos, visto que o
Console.WriteLine
não funciona nos testes. Exemplo:
/// <inheritdoc />
public AcmeTests(ITestOutputHelper output) : base(output)
{
}
- Na definição do seu método de teste (ex: Fact), instancie a classe SutFactory no campo _sut que está definido na classe BaseTests:
_sut = new SutFactory(
8001,
_output,
builder =>
{
// defina as suas injeções aqui
},
application => {
// defina os seus endpoints e middlewares aqui
}
);
O primeiro parâmetro da instância é a porta da "api" que será levantada durante a execução do teste, defina valores diferentes para cada classe de teste, pode ser interessante criar uma constante na classe.
- Agora é necessário iniciar a instância, aqui você controla se vai usar containers ou não:
await _sut.UseSqlServerContainer();
Inicialização sem nenhum container definido.
await _sut.UseRedisContainer()
.UseSqlServerContainer()
.InitializeAsync();
Inicialização feita com os containers de redis e sqlserver.
Após a incialização, as dependências injetadas podem ser obtidas através do método
_sut.GetDependency<T>
, exemplo:
var configuration = _sut.GetDependency<IConfiguration>();
Buscando a instância do IConfiguration que foi injetada.
Exemplo de um método de teste completo:
[Fact]
public async Task EnviarAvaliacao_DbInterceptorThrowsException_ReturnsDomainErrorCode()
{
// Arrange
await ArrangeApi(builder =>
{
builder.Services
.RemoveAll<BaseAvaliaEsContext>()
.RemoveAll<DbContextOptions<BaseAvaliaEsContext>>();
builder.Services
.AddDbContext<BaseAvaliaEsContext, TestAvaliaEsContext>();
});
await Task.Delay(1);
var dbContext = _sut!.GetDependency<BaseAvaliaEsContext>();
var httpClient = _sut.GetDependency<IHttpClientFactory>()
.CreateClient();
var chaveAvaliacao = new ChaveAvaliacao
{
Data = DateTimeOffset.Now,
IdExterno = Guid.NewGuid(),
IdServico = Guid.Parse(Constants.GuidPrimeiraViaRg),
IdSistema = Guid.Parse(Constants.GuidConectaEs),
UrlRetorno = "https://foo.bar"
};
await dbContext.Database
.EnsureCreatedAsync();
await dbContext.ChaveAvaliacoes
.AddAsync(chaveAvaliacao);
await dbContext.SaveChangesAsync();
var avaliacaoDto = new AvaliacaoEnvioDto
{
ChaveAvaliacao = chaveAvaliacao.IdExterno,
IdCidadao = Guid.NewGuid(),
Nota = 5,
Opcoes = new List<Guid>()
};
// Act
var response = await httpClient.PostAsJsonAsync(
$"http://localhost:{ApiPort}/EnviarAvaliacao", avaliacaoDto
);
var result = await response.Content
.ReadFromJsonAsync<Result<bool>>();
// Assert
result.Should()
.NotBeNull();
result!.IsOk()
.Should()
.BeFalse();
result.ErrorCode
.Should()
.NotBeNullOrEmpty()
.And
.Be(DomainErrorCodes.ErroAoSalvarAvaliacao);
}
private async Task ArrangeApi(
Action<WebApplicationBuilder>? configureBuilder = null,
[CallerMemberName] string? memberName = ""
)
{
_sut = new SutFactory(
ApiPort,
_output,
builder =>
{
builder.Services
.AddHttpClient();
builder.Services
.AddDbContext<BaseAvaliaEsContext, AvaliaEsContext>();
builder.Services
.InjectAcessoCidadaoIntegration(builder.Configuration)
.InjectAllDependencies()
.RemoveUnwantedServices(
typeof(IAvaliacaoApiService)
);
configureBuilder?.Invoke(builder);
},
application =>
{
application.Map(
"EnviarAvaliacao",
async (AvaliacaoEnvioDto dto, [FromServices] IAvaliacaoPublicoService service)
=> await service.EnviarAvaliacao(dto)
);
application.Map(
"ObterDadosChaveAvaliacao",
async (ObterDadosAvaliacaoDto dto, [FromServices] IAvaliacaoPublicoService service)
=> await service.ObterDadosChaveAvaliacao(dto)
);
application.Map(
"ObterOpcoesAvaliacao",
async ([FromServices] IAvaliacaoPublicoService service)
=> await service.ObterOpcoesAvaliacao()
);
},
memberName
);
await _sut.UseRedisContainer()
.UseSqlServerContainer()
.InitializeAsync();
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- CliWrap (>= 3.6.4)
- Docker.DotNet (>= 3.125.15)
- Pastel (>= 4.2.0)
- Prodest.Cache (>= 0.1.17)
- Prodest.Logging (>= 6.0.10)
- StackExchange.Redis (>= 2.7.4)
- xunit (>= 2.6.2)
-
net7.0
- CliWrap (>= 3.6.4)
- Docker.DotNet (>= 3.125.15)
- Pastel (>= 4.2.0)
- Prodest.Cache (>= 0.1.17)
- Prodest.Logging (>= 6.0.10)
- StackExchange.Redis (>= 2.7.4)
- xunit (>= 2.6.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.