...
...
...
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn( typeof(AppModule), typeof(TnfTestBaseModuleTnfAppTestBaseModule))] public class EfCoreAppTestModule : TnfModule { public override void PreInitialize() { Configuration.Modules .TnfEfCoreInMemory(IocManager.IocContainer) .RegisterDbContextInMemory<ArchitectureDbContext>(); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } |
...
Também temos como dependência o modulo "TnfTestBaseModuleTnfAppTestBaseModule" do TNF carregando toda a estrutura de testes integrados.
...
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn( typeof(AppModule), typeof(TnfTestBaseModuleTnfAppTestBaseModule))] public class NSubstituteAppTestModule : TnfModule { public override void PreInitialize() { // Mock repositories Configuration.ReplaceService<IWhiteHouseRepository>(() => { var instance = Substitute.For<IWhiteHouseRepository>(); var presidentToInsert = new PresidentDto("1", "New President", "55833479"); instance.InsertPresidentsAsync(Arg.Any<List<PresidentDto>>) .Returns(Task.FromResult(presidentToInsert)); IocManager.IocContainer.Register( Component .For<IWhiteHouseRepository>() .Instance(instance) .LifestyleTransient() ); }); } public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } } |
...
Também temos como dependência o modulo "TnfTestBaseModuleTnfAppTestBaseModule" para carregar a estrutura de testes integrados.
...
Após a definição do módulo vamos criar a classe de Setup para cada teste integrado: para isso a classe abaixo nomeada de "NSubstituteAppTestBase" realiza a herança da classe "TnfEfCoreIntegratedTestBase<Module>TnfAppIntegratedTestBase<Module>" que recebe um TnfModule (implementado anteriormente):
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class NSubstituteAppTestBase : TnfIntegratedTestBase<NSubstituteAppTestModule>TnfAppIntegratedTestBase<NSubstituteAppTestModule> { } |
A classe TnfIntegratedTestBase está TnfAppIntegratedTestBase está contida no pacote Tnf.App.TestBase.
Definido nosso setup podemos implementar nossa classe e realizar os testes usando nosso repositório criado com NSubstitute.
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class WriteHouseAppServiceTests : NSubstituteAppTestBase { private readonly IWhiteHouseAppService _whiteHouseAppService; public WriteHouseAppServiceTests() { _whiteHouseAppService = LocalIocManager.Resolve<IWhiteHouseAppService>(); } [Fact] public async Task Should_Insert_President_With_Success() { // Act var response = await _whiteHouseAppService.InsertPresidentAsync(new PresidentDto("1", "New President", "12345678")); // Assert Assert.TrueFalse(responseLocalNotification.SuccessHasNotification()); } } |
Podemos perceber que toda a estrutura de Injeção de dependência ainda é mantida inclusive nos testes.
...
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[DependsOn( typeof(AppModule), typeof(TnfAspNetCoreTestBaseModuleTnfAppAspNetCoreTestBaseModule))] 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()); } } } |
...
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 TnfAspNetCoreTestBaseModuleTnfAppAspNetCoreTestBaseModule.
Como estamos criando um teste para uma aplicação ASP .NET Core que expoe expõe nossas APIs, temos que criar uma classe de startup que fará a configuração de nosso pipeline:
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class StartupTest { public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc() .AddApplicationPart(typeof(TnfAspNetCoreModule).GetAssembly()) .AddMvcCore() .AddApplicationPart(typeof(Tnf.Architecture.Web.Startup.WebModule).GetAssembly()) .AddControllersAsServices(); services.AddEntityFrameworkInMemoryDatabase(); // Configure Tnf and Dependency Injection return services.AddTnf<AppTestModule>AddTnfApp<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?}"); }); } } |
...
...
Bloco de código | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class WhiteHouseControllerTests : AppTestBase { [Fact] public void Should_Resolve_Controller() { ServiceProvider.GetService<WhiteHouseController>().ShouldNotBeNull(); } [Fact] public async Task GetAll_Presidents_With_Success() { // Act var response = await GetResponseAsObjectAsync<AjaxResponse<PagingDtoResponse<PresidentDto>>>GetResponseAsObjectAsync<ListDto<PresidentDto>>( "/api/white-house?offset=0&pageSize=10", HttpStatusCode.OK ); // Assert Assert.True(response.Success); Assert.Equal(response.Result.Data.Count, 6); response.Result.Notifications.ShouldBeEmpty(); } [Fact] public async Task GetAll_Presidents_With_Invalid_Parameters() { // Act var response = await GetResponseAsObjectAsync<AjaxResponse<string>>( "/api/white-house?offset=0&pageSize=0", HttpStatusCode.BadRequest ); response.Success.ShouldBeTrue(); response.Result.ShouldBe($"Invalid parameter: pageSize" $"{RouteConsts.WhiteHouse}?pageSize=5", HttpStatusCode.OK ); // Assert Assert.Equal(response.Items.Count, 5); } [Fact] public async Task GetAll_Presidents_With_Invalid_Parameters_Return_Bad_Request() { // Act var response = await GetResponseAsObjectAsync<ErrorResponse>( $"{RouteConsts.WhiteHouse}", HttpStatusCode.BadRequest ); // Assert response.Message.ShouldBe("GetAllPresident"); response.DetailedMessage.ShouldBe("GetAllPresident"); Assert.True(response.Details.Any(n => n.Message == Error.InvalidParameter.ToString())); } } |
Em nossa classe de teste temos acesso a alguns métodos pela herança da classe TnfAspNetCoreIntegratedTestBase contida dentro do pacote Tnf.AspNetCore.TestBase para criação de testes em serviços.
...