Mocking HTTP calls in ASP.NET Integration Tests
When working with services that call external APIs, you'll probably want to mock those calls in your tests. This process is straightforward when working with a single service. You typically mock the HttpHandler
in the HttpClient
passed to the service:
var handlerMock = new Mock<HttpMessageHandler>();
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{\"message\":\"Hello World!\"}")
});
var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri("https://api.example.com/")
};
How would you go about doing that in an Integration Testing scenario, where services get wired up by the framework?
ASP.NET has a nifty way of hosting your ASP.NET API in memory using the Microsoft.AspNetCore.Mvc.Testing package. It takes just a few lines of code to fire up an in-memory API, but mocking the external calls becomes tricky unless you want to replace every single service registration with a custom HttpClient
+ mocked handler combo. There's an easier way: you can register a custom HttpMessageHandlerBuilder
.