Table of Contents

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.

Progress Telerik

Premium sponsor: Progress Telerik.

Packt

Editorial support provided by Packt.

.NET Foundation

Supported by the .NET Foundation.