简体   繁体   中英

HttpClient with BaseAddress not working (production + integration test)?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM