Unit Test and Mock HttpClientFactory in .NET Core

Mock HttpClientFactory

In this article, we will see how to Unit Test and Mock HttpClientFactory in .NET Core with proper mocking techniques in .NET Core.

As we learned in our last article of best practices that HTTTPClient object should be created using HttpClientFactory as it provides multiple benefits.

In this article, we will see another benefit of using this interface i.e easy to unit test.

Today in this article, we will cover below aspects,

HttpClientFacory can also be used in the others way like using Named HTTPClient and Typed HTTPClient

Unit Test and Mocking HttpClientFactory-Basic and Named

Today in this post we will see how to mock basic or named HttpClientFactory interface.

Below is a sample code API created using ASP.NET Core 3.1, which we shall be unit testing and mocking.

The below code demonstrates Basic and Named HTTPClient usage which we shall be unit testing and mocking using XUnit and Moq.

  
        [HttpGet]
        public async Task<IActionResult> OnGetAccount()
        {
            var uri = new Uri("https://localhost:44364/account");

            var client = _clientFactory.CreateClient();

            var response = await client.GetAsync(uri);

            if (response.IsSuccessStatusCode)
            {
                return Ok(response.Content.ReadAsStreamAsync().Result);
            }
            else
            {
                return StatusCode(500, "Something Went Wrong! Error Occured");
            }
        }

If using Named HTTPClient request object then please update the CreateClient() method with the name of the HTTP object,

var client = _clientFactory.CreateClient("PaymentClient");

Below is the Controller constructor accepting the IHttpClientFactory interface which is DI through the Constructor.

    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
        private readonly IHttpClientFactory _clientFactory;
        public AccountController(IHttpClientFactory clientFactory)
        {
            _clientFactory = clientFactory;
        }
..
..


1. Mock IHttpClientFactory interface

So as a first step we should be mocking IHttpClientFactory and all its extension methods.

Being an interface IHttpClientFactory is very easy to mock as below,

             //Arrange
            var mockFactory = new Mock<IHttpClientFactory>();

2. Mock HTTPClient object

We need to create explicit actual HTTPClient mock objects to pass to the extension method of IHttpClientFactory i.e CreateClient().

The best way to create a mock HTTPClient instance is by mocking HttpMessageHandler. Mocking of HttpMessageHandler will also ensure the client calling actual endpoints are faked by intercepting it.

Below is the complete code,

var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
            mockHttpMessageHandler.Protected()
                .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
                .ReturnsAsync(new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.OK,
                    Content = new StringContent("{'name':thecodebuzz,'city':'USA'}"),
                });



            var client = new HttpClient(mockHttpMessageHandler.Object);
            mockFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(client);

So far so good.

3. Controller with mocked IHttpClientFactory

AccountController controller = new AccountController(mockFactory.Object);

All the above 3 steps ensure our Arrange steps are properly configured within Unit Testing.

Let’s Invoke the method as below,

            //Act
            var result = await controller.OnGetAccount() as ObjectResult;

4. Assert the Results

              //Assert
             Assert.NotNull(result);
             Assert.Equal(HttpStatusCode.OK,(HttpStatusCode)result.StatusCode);

Finally, we are all set with the results and our Unit test cases pass successfully.

Unit Test and Mock HttpClientFactory

Mock Typed HTTPClient

Please refer to the below post on mocking the Typed HTTPClient request object.

Using MS Test framework to Mock HttpClientFactory

You can leverage MSTes or Nunit Test framework similar way to write Unit test cases for code containing HttpClientFactory.

References:

That’s All, Happy coding !!. If you have any better suggestions, please sound off your comments below.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.