I'm trying to test the health check endpoint.
I've implemented an integration test with .net core and WebApplicationFactory and TestServer, in order to test my API endpoints.
I wrote test cases(xUnit) to test my API endpoints, the simple API controllers work just fine, but it's not found the Health check endpoint - it is not a controller, it's a configurable endpoint
Here is the service configuration
services.AddHealthChecks().AddCheck<PingHealthCheck>("ping_health_check");
Here is the configuration
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
// Prevent response caching
AllowCachingResponses = false,
ResponseWriter = (context, report) => context.Response
//Return an object instead of a plain text
.WriteAsync(JsonConvert.SerializeObject(new {status= report.Status.ToString() })),
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
})
And here is the test case
[Fact]
public async Task Call_Health_Return_Healthy()
{
//Arrange
//Act
var response = await _factory.TestHttpClient
.GetAsync("/health");
//Assert
response.StatusCode.Should().BeEquivalentTo(HttpStatusCode.OK);
}
I successfully resolved my issue. The cause was a configuration of which hosts were allowed to access the health endpoint.
The issue was, that I restrict the access (in localhost) to port 5001, but the TestServer in the ApplicationFactory doesn't have any port.
Here is the configuration code
/// <summary>
/// Configures the endpoint.
/// </summary>
/// <param name="builder">The application builder. <see cref="IApplicationBuilder"/></param>
/// <param name="configuration">The IConfiguration builder instance</param>
public static void ConfigureEndpoint(this IApplicationBuilder builder, IConfiguration configuration)
{
var healthConfiguration = configuration.GetSection(nameof(HealthConfiguration)).Get<HealthConfiguration>();
builder.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
// Prevent response caching
AllowCachingResponses = false,
ResponseWriter = (context, report) => context.Response
//Return an object instead of a plain text
.WriteAsync(JsonConvert.SerializeObject(new {status = report.Status.ToString()})),
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
}).RequireHost(string.Join(",",healthConfiguration.Hosts.Select(host=>host)));
});
}
Whereas the config section changed to
"HealthConfiguration": {
"Hosts": ["localhost"]
},