I'm using Specflow as BDD testing framework and Fluent docker to spin up API container before each tests using docker compose file.
I put a breakpoint before sending a http request to test if the container is up and my app is running perfectly.
I open app swagger and hit endpoints and everything works. I added http request logging to check if request url is valid. Everything seems to be configured properly until this line:
var response = await _httpClient.PostAsJsonAsync(UserEndpoint, request);
This is console log
using Ardalis.ListStartupServices;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using UserSegmentation.Core;
using UserSegmentation.Infrastructure;
using UserSegmentation.Infrastructure.Data;
using UserSegmentation.Web;
using Serilog;
using UserSegmentation.Application;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.UseSerilog((_, config) => config.ReadFrom.Configuration(builder.Configuration));
// builder.Services.Configure<CookiePolicyOptions>(options =>
// {
// options.CheckConsentNeeded = _ => true;
// options.MinimumSameSitePolicy = SameSiteMode.None;
// });
var connectionString =
builder.Configuration
.GetConnectionString("SqliteConnection"); //Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext(connectionString!);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices
builder.Services.Configure<ServiceConfig>(config =>
{
config.Services = new List<ServiceDescriptor>(builder.Services);
// optional - default path to view services is /listallservices - recommended to choose your own path
config.Path = "/listservices";
});
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterModule(new DefaultCoreModule());
containerBuilder.RegisterModule(
new DefaultInfrastructureModule(builder.Environment.EnvironmentName == "Development"));
containerBuilder.RegisterModule(
new ApplicationModule());
});
builder.Services.AddHealthChecks();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseShowAllServicesMiddleware();
}
// app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.UseFluentValidationExceptionHandler();
app.MapHealthChecks("/healthz");
// Seed Database
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<AppDbContext>();
context.Database.EnsureCreated();
SeedData.Initialize(services);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB. {exceptionMessage}", ex.Message);
}
}
app.Run();
My hooks config
[BeforeScenario]
public void SetupClient()
{
var config = LoadConfiguration();
var apiUrl = config["Users.Api:BaseAddress"] ?? "http://localhost:8080";
var httpClient = new HttpClient(new LoggingHandler(new HttpClientHandler())) {
BaseAddress = new Uri(apiUrl)
};
httpClient.DefaultRequestHeaders.Add("accept", "*/*");
_objectContainer.RegisterInstanceAs(httpClient);
var dockerConfig = new DockerConfiguration();
_objectContainer.RegisterInstanceAs(dockerConfig);
}
[BeforeTestRun]
public static void DockerComposeUp(DockerConfiguration dockerHandling)
{
dockerHandling.DockerComposeUp();
}
[AfterTestRun]
public static void DockerComposeDown(DockerConfiguration dockerHandling)
{
dockerHandling.DockerComposeDown();
}
My docker config
_compositeService = new Builder()
.UseContainer()
.UseCompose()
.FromFile(dockerConfigurationFile)
.WaitForHttp("user-segmentation", "http://localhost:8080/healthz",
continuation: (resp, _) => resp.Code == HttpStatusCode.OK ? 0 : 2000)
.RemoveOrphans()
.Build()
.Start();