Mocking HttpClient
Mocking the HttpClient
service in .NET Core is a bit more cumbersome than interface-based services like IJSRuntime
.
There is currently no built-in mock for HttpClient
in bUnit, but with the use of
RichardSzalay.MockHttp we can easily add one that works
with bUnit.
To use RichardSzalay.MockHttp, add the following package reference to your test project's .csproj
file:
<PackageReference Include="RichardSzalay.MockHttp" Version="6.0.0" />
To make it easier to work with RichardSzalay.MockHttp, add
the following extension class to your test project. It makes it easier to add the HttpClient
mock to
bUnit's test context's Services
collection, and configure responses to requests:
using Bunit;
using Microsoft.Extensions.DependencyInjection;
using RichardSzalay.MockHttp;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
public static class MockHttpClientBunitHelpers
{
public static MockHttpMessageHandler AddMockHttpClient(this TestServiceProvider services)
{
var mockHttpHandler = new MockHttpMessageHandler();
var httpClient = mockHttpHandler.ToHttpClient();
httpClient.BaseAddress = new Uri("http://localhost");
services.AddSingleton<HttpClient>(httpClient);
return mockHttpHandler;
}
public static MockedRequest RespondJson<T>(this MockedRequest request, T content)
{
request.Respond(req =>
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(JsonSerializer.Serialize(content));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return response;
});
return request;
}
public static MockedRequest RespondJson<T>(this MockedRequest request, Func<T> contentProvider)
{
request.Respond(req =>
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(JsonSerializer.Serialize(contentProvider()));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return response;
});
return request;
}
}
With the helper methods in place, you can do the following in your tests:
var mock = Services.AddMockHttpClient();
mock.When("/getData").RespondJson(new List<Data>{ ... });
This registers the mock HttpClient
in bUnit's test context's Services
collection, and then tells the mock that when a request is received for /getData
, it should respond with the new List<Data>{ ... }
, serialized as JSON.
Tip
You can add additional RespondXXX
methods to the MockHttpClientBunitHelpers
class to fit your testing needs.