Pular para o conteúdo principal
Versão: main (dev) 🚧

ITLab.Template.DevPack.Testing

Helpers de teste shipados como pacote NuGet auxiliar para projetos consumidores do ITLab.Template.DevPack. Resolve três fricções recorrentes em testes de integração:

  1. Provider conflict quando o app de produção registra SqlServer/Postgres e o teste quer EF Core InMemory — UseIsolatedInMemoryProvider mantém um service provider EF separado para o InMemory.
  2. Authentication scaffoldingTestAuthenticationHandler aceita roles via header X-Test-Roles e produz um ClaimsPrincipal autenticado com essas roles.
  3. WebApplicationFactory boilerplateWebApplicationFactoryBase<TProgram, TDbContext> encapsula DB name único por instância, substituição do DbContextOptions, registro do test auth scheme e helpers de cliente (CreateClientWithRoles, CreateAnonymousClient).

Namespace: using ITLab.Template.DevPack.Testing; (factory base e ponto de entrada), using ITLab.Template.DevPack.Testing.Authentication; (handler) e using ITLab.Template.DevPack.Testing.Persistence; (UseIsolatedInMemoryProvider).

Componentes

TipoNomeResponsabilidade
Abstract ClassWebApplicationFactoryBase<TProgram, TDbContext>WebApplicationFactory parametrizada — substitui DbContextOptions<TDbContext>, registra TestAuthenticationHandler como esquema default, expõe CreateClientWithRoles / CreateAnonymousClient e o hook ConfigureAdditionalServices
Sealed ClassTestAuthenticationHandlerLê roles do header X-Test-Roles, emite ClaimsPrincipal autenticado
Static ClassIsolatedInMemoryProviderExtensionsDbContextOptionsBuilder.UseIsolatedInMemoryProvider(databaseName) — InMemory com IServiceProvider interno isolado
ClassCurrentUserBuilderBuilder fluente para mock de ICurrentUser (Moq)
Static ClassDateTimeProviderBuilderHelpers para mock de IDateTimeProvider
Static ClassObjectArrayExtensionsHelpers de assertion sobre object[] (extração tipada)

Como usar

1. Criar a factory específica do projeto

public sealed class MyAppIntegrationTestFactory
: WebApplicationFactoryBase<Program, AppDbContext>
{
protected override void ConfigureAdditionalServices(IServiceCollection services)
{
// Mocks/fakes específicos do projeto, se houver.
services.RemoveAll<IExternalApiClient>();
services.AddSingleton<IExternalApiClient>(new FakeExternalApiClient());
}
}

2. xUnit fixture + cliente com roles

public class CriarPedidoEndpointTests : IClassFixture<MyAppIntegrationTestFactory>
{
private readonly MyAppIntegrationTestFactory _factory;

public CriarPedidoEndpointTests(MyAppIntegrationTestFactory factory)
=> _factory = factory;

[Fact]
public async Task Post_AsAuthorized_Returns201()
{
var client = _factory.CreateClientWithRoles("Pedidos.Create");
var response = await client.PostAsJsonAsync("/pedidos", new { Cliente = "Acme", Total = 100 });
response.StatusCode.Should().Be(HttpStatusCode.Created);
}

[Fact]
public async Task Post_AsAnonymous_Returns401()
{
var client = _factory.CreateAnonymousClient();
var response = await client.PostAsJsonAsync("/pedidos", new { Cliente = "Acme", Total = 100 });
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
}

3. Usando UseIsolatedInMemoryProvider diretamente

A WebApplicationFactoryBase já chama internamente. Use diretamente quando estiver fora do contexto de WebApplicationFactory (ex.: testes de repositório isolados):

var options = new DbContextOptionsBuilder<AppDbContext>()
.UseIsolatedInMemoryProvider("test-db")
.Options;
using var db = new AppDbContext(options);

O que não fazer

  • Não importar este pacote em código de produção — tem Microsoft.AspNetCore.Mvc.Testing e Moq como deps transitivas.
  • Não habilitar o TestAuthenticationHandler em ambientes de produção (não é gated automaticamente; a inclusão é responsabilidade do WebApplicationFactoryBase, que só roda em testes).

Extensão pelo produto

  • Subclasses de WebApplicationFactoryBase podem sobrescrever ConfigureAdditionalServices para registrar mocks/fakes específicos.
  • O claimsMapper opcional do DevPackIdentityContextMiddleware (no pacote principal) é independente do TestAuthenticationHandler — em testes, o handler já produz claims compatíveis com o mapper default.