Search code examples
c#.net-coreintegration-testinghealth-check

.net 5.0 Integration Test, Health check endpoint not found


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);
}

Solution

  • 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"] 
      },