| Índice |
|---|
Testes de integração compreendem a segunda fase do ciclo de testes de uma aplicação.
...
As estruturas de asserts dos testes descritos abaixo foram criados usando o Xunit e o Shouldly.
Testes na camada de aplicação
Para criar testes dessa camada temos que analisar o que sua aplicação utiliza como infraestrutura.
...
| Bloco de código | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn(
typeof(AppModule),
typeof(TnfTestBaseModule))]
public class AppTestModule : TnfModule
{
public override void PreInitialize()
{
// Mock repositories
Configuration.ReplaceService<IWhiteHouseRepository>(() =>
{
var instance = Substitute.For<IWhiteHouseRepository>();
var presidentsToInsert = new List<PresidentDto>()
{
new PresidentDto("1", "New President", "55833479")
};
instance.InsertPresidentsAsync(presidentsToInsertArg.Any<List<PresidentDto>>)
.Returns(Task.FromResult(presidentsToInsert));
IocManager.IocContainer.Register(
Component
.For<IWhiteHouseRepository>()
.Instance(instance)
.LifestyleTransient()
);
});
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
} |
...
Todos os testes integrados visto até o presente momento podem ser aplicados no teste da camada de serviço.
Recapitulando o que vimos até o presente momento em nossos testes integrados: testamos a nossa camada de aplicação utilizando banco em memoria (Entity Framework Core) e usando uma estrutura de mock (NSubstitute).
Para testar nossa camada de serviços podemos unir os dois conceitos de testes partindo do principio que nossa aplicação pode ter N fontes de dados (Infraestrutura) e independente de qual sejam elas, precisamos criar testes para validar nossa regra de negocio.
Vamos começar com a criação de nosso modulo que fará o carregamento da estrutura dos testes:
| Bloco de código | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn(
typeof(AppModule),
typeof(TnfAspNetCoreTestBaseModule))]
public class AppTestModule : TnfModule
{
public override void PreInitialize()
{
Configuration.Auditing.IsEnabledForAnonymousUsers = true;
// Mock repositories
Configuration.ReplaceService<IWhiteHouseRepository, WhiteHouseRepositoryMock>();
Configuration.Modules
.TnfEfCoreInMemory(IocManager.IocContainer, IocManager.Resolve<IServiceProvider>())
.RegisterDbContextInMemory<ArchitectureDbContext>();
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(AppTestModule).GetAssembly());
}
}
} |
Note que nosso module ainda contem a mesma estrutura de antes usando a função ReplaceService para substituir o repositorio que será injetado (nesse caso para elucidar não foi usado o NSubstitute, foi criado uma classe concreta) e configurado o Entity Framework Core para trabalhar em memoria.
Nosso modulo agora contem dependências diferente pois vamos testar uma camada de AspNetCore e por isso devemos deixar explicito em nosso atributo "DependsOn" o uso do modulo TnfAspNetCoreTestBaseModule.
Como estamos criando um teste para um contexto web temos que criar uma classe de startup que fará a configuração de nosso pipeline para AspNetCore:
| Bloco de código | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
public class StartupTest
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddApplicationPart(typeof(TnfAspNetCoreModule).GetAssembly())
.AddApplicationPart(typeof(Tnf.Architecture.Web.Startup.WebModule).GetAssembly())
.AddControllersAsServices();
services.AddEntityFrameworkInMemoryDatabase();
//Configure Tnf and Dependency Injection
return services.AddTnf<AppTestModule>(options =>
{
//Test setup
options.SetupTest();
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseTnf(); //Initializes Tnf framework.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
} |
Dessa forma podemos criar um setup para cada teste integrado que for realizado:
| Bloco de código | ||||||||
|---|---|---|---|---|---|---|---|---|
| ||||||||
public abstract class AppTestBase : TnfAspNetCoreIntegratedTestBase<StartupTest>
{
protected override void InitializeIntegratedTest()
{
IocManager.UsingDbContext<ArchitectureDbContext>(
context =>
{
context.Countries.Add(new Country(1, "Brasil"));
context.Countries.Add(new Country(2, "EUA"));
context.Countries.Add(new Country(3, "Uruguai"));
context.Countries.Add(new Country(4, "Paraguai"));
context.Countries.Add(new Country(5, "Venezuela"));
});
}
} |
Note que aqui usamos para cada teste a herança da classe que o TNF disponibiliza chamada TnfAspNetCoreIntegratedTestBase. Essa classe foi criada para auxiliar em cenários de teste como esse onde precisamos testas um contexto AspNetCore.
Essa classe prove algumas facilitadores para realizar chamadas para nossa aplicação web de testes.