I have this simple setup for a .NET Core project which is just a very basic HttpClient usage to do some simple integration tests to a RESTful API. For now the test project remains separated from the main API project, that's why it's built on .NET Core for now, using NUnit as test framework as well. But because of that I have the freedom to change it anytime.
For now, the implementation is very simple, like this:
public static HttpClient _client1; public static HttpClient _client2; [OneTimeSetUp] public void OneTimeSetUp() { _client1 = new HttpClient {BaseAddress = new Uri("https://address1.com")}; _client1.DefaultRequestHeaders.Add("API-KEY", "token_here"); _client2 = new HttpClient {BaseAddress = new Uri("https://address2.com")}; _client1.DefaultRequestHeaders.Add("API-KEY", "token_here"); } //[OneTimeTearDown] //public void OneTimeTearDown() //{ //_client1?.Dispose(); //_client2?.Dispose(); //}
That's the main test class, but considering that later it will become a more robust test suite and it's going to be added on main project, I've found that I can use HttpClientFactory
like this, which produces the same test results and I can modelate the services to be added to the API solution later.
public static HttpClient _client1; public static HttpClient _client2; [OneTimeSetUp] public void OneTimeSetUp() { var services = new ServiceCollection(); services.AddHttpClient("Client1", client => { client.BaseAddress = new Uri("https://address1.com/"); client.DefaultRequestHeaders.Add("KEY", "token_here"); }); services.AddHttpClient("Client2", client => { client.BaseAddress = new Uri("https://address2.com/"); client.DefaultRequestHeaders.Add("KEY", "token_here"); }); var factory = services.BuildServiceProvider().GetService<IHttpClientFactory>(); _client1 = factory.CreateClient("Client1"); _client2 = factory.CreateClient("Client2"); } //[OneTimeTearDown] //public void OneTimeTearDown() //{ //_client1?.Dispose(); //_client2?.Dispose(); //}
My main problem is that we have two main API addresses that will be used under production environment and I'm not sure if this implementation is appropriated. Everything works as expected on both scenarios when called on tests...
[TestFixture, Parallelizable(ParallelScope.All)] public class TestCase : Setup { [Test] public async Task Get() { var response = await _client1.GetAsync("v1/Endpoint"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadAsStringAsync(); Assert.NotNull(response); Console.WriteLine(JToken.Parse(result)); } }
So it will be the same for _client2
and in a lot of tests...
As I said, it works as expected on both ways, but since I'm new at this and didn't found much about this kind of integration test separated from the main API reference project, I'm not so sure about how I built it, so any other and more experienced views about it will be very much appreciated.
EDIT: I had the need to run all the tests in parallel, so I was generating an ObjectDisposedException
with the Parallelizable
attribute. Removing the OneTimeTearDown
with the client disposing calls solved the problem, but I have doubts if that's the correct way to use HttpClient as well, as it still gives the expected results.