I have an ASP.NET Core 5 application running in IIS in production + I have integration tests for the application. And I have a problem that I do not know how to setup my HttpClient in integration tests to work both with "production" server (service running on my local IIS) and the TestServer.
This is how I am instantiating the HttpClient:
private static HttpClient GetHttpClient(bool isProductionServer)
{
if (isProductionServer)
{
return new HttpClient {BaseAddress = new Uri("http://localhost/myservice/")};
}
var appFactory = new WebApplicationFactory<Startup>();
var testClient = appFactory.CreateClient();
return testClient;
}
As explained in Why is HttpClient BaseAddress not working?, slash must be present at the end of BaseAddress
and later, slash must not be present at the beginning of the relative URI.
But it seems that the test HttpClient created from WebApplicationFactory
has the opposite requirement that slash must be present at the beginning of the relative URI. Since I am getting the relative URI from the same place, this is causing me problems. My tests are getting the httpClient instance from a base test class, and the tests should not care if they are executed against IIS or TestServer. Any idea how to make this work? Maybe some setting when creating the httpClient for the TestServer?
To further illustrate the problem, please take a look at the following two tests:
[Test]
public async Task TestRequestOnTestServer()
{
// works only for: "/api/v1/ping", but not for "api/v1/ping" - I get 404 response
string route = ApiRoutes.V1.Health.PingGet;
var client = GetHttpClient(false);
var response = await client.GetAsync(route);
Assert.That(response.IsSuccessStatusCode);
}
[Test]
public async Task TestRequestOnProductionServer()
{
// works only for: "api/v1/ping", but not for "/api/v1/ping" - I get 404 response
string route = ApiRoutes.V1.Health.PingGet;
var client = GetHttpClient(true);
var response = await client.GetAsync(route);
Assert.That(response.IsSuccessStatusCode);
}
Maybe HttpClient created from WebApplicationFactory
does not have the behavior I assumed it has. Turns out the problem was in the Controller class which had the [Route("[controller]")]
attribute, and the Ping method inside it had [Route(ApiRoutes.V1.Health.PingGet)]
.
In IIS ping was available at "/api/v1/ping"
(not sure why), but when starting from VisualStudio swagger showed that the actual endpoint was "/Health/api/v1/ping"
(which is wrong).
Removing the [Route("[controller]")]
attribute fixed the problem and now both tests pass.