Verify that my DelegatingHandler was added to IHttpClientBuilder

701 Views Asked by At

I have code which adds a named HttpClient to the ServiceCollection and adds a DelegatingHandler to the client. Example code:

public class MyDelegatingHandler : DelegatingHandler
{
    // ...
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
            services.AddHttpClient("MyClient")
                .AddHttpMessageHandler(provider => new MyDelegatingHandler());
        });

When writing unit tests, how can I verify that the DelegatingHandler implementation added was MyDelegatingHanlder?

1

There are 1 best solutions below

4
On BEST ANSWER

This information is stored down in a private field of the HttpClient. You can get at it, but it's a tad unorthodox. So, you may or may not be interested, but I am going to throw this out there in case you are:

public static class HttpClientExtensions
{
    public static bool ContainsDelegatingHandler<TDelegatingHandler>(
        this HttpClient httpClient) where TDelegatingHandler: DelegatingHandler
    {
        if(httpClient == null)
        {
            throw new ArgumentNullException(nameof(httpClient));
        }

        var internalHandlerField = typeof(HttpMessageInvoker).GetField(
            "_handler", BindingFlags.NonPublic | BindingFlags.Instance);
        if(internalHandlerField == null)
        {
            throw new InvalidOperationException(
                "_handler no longer exists as a private instance field of HttpClient");
        }

        // run down the chain of delegating handlers until there are no more
        var delegatingHandler = internalHandlerField.GetValue(httpClient) as DelegatingHandler;
        while (delegatingHandler != null)
        {
            if(delegatingHandler.GetType() == typeof(TDelegatingHandler))
            {
                return true;
            }
            delegatingHandler = delegatingHandler.InnerHandler as DelegatingHandler;
        }

        return false;
    }
}

To test, you'd first have to create an HttpClient using the factory:

var httpClient = httpClientFactory.CreateClient("MyClient");

Then run it through the extension:

if(!httpClient.ContainsDelegatingHandler<MyDelegatingHandler>())
{
    throw new Exception(
        "HttpClient with name 'MyClient' does not contain " +
        $"{nameof(MyDelegatingHandler)} delegating handler.");
}