添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I wasn't able to find any info how to use MockHttp with Asp.Net Core, WebApplicationFactory, and IServiceCollection.AddHttpClient methods.

In the I was able to achieve what I wanted by looking at DefaultHttpClientFactory and implementing by own factory (and replacing original IHttpClientFactory in IServiceCollection):

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http;
using Microsoft.Extensions.Options;
using RichardSzalay.MockHttp;
using System;
using System.Net.Http;
namespace HttpTests
    public class MockHttpClientFactory : IHttpClientFactory
        private readonly IServiceProvider _services;
        private readonly MockHttpMessageHandler _mockHttpMessageHandler;
        public MockHttpClientFactory(IServiceProvider services, MockHttpMessageHandler mockHttpMessageHandler)
            _services = services;
            _mockHttpMessageHandler = mockHttpMessageHandler;
        public HttpClient CreateClient(string name)
            var httpClientOptions = _services.GetRequiredService<IOptionsMonitor<HttpClientFactoryOptions>>().Get(name);
            var httpHandlerBuilder = _services.GetRequiredService<HttpMessageHandlerBuilder>();
            httpHandlerBuilder.Name = name;
            httpHandlerBuilder.PrimaryHandler = _mockHttpMessageHandler;
            foreach (var action in httpClientOptions.HttpMessageHandlerBuilderActions)
                action(httpHandlerBuilder);
            var client = new HttpClient(httpHandlerBuilder.Build());
            foreach (var action in httpClientOptions.HttpClientActions)
                action(client);
            return client;

Would it make sense to add something like that to MockHttp?

Hi @Dreamescaper
I was looking for something similar and found your issue.

MockHttpClientFactory could be simpler.

My final solution:

MockHttpClientFactory:

using RichardSzalay.MockHttp;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
namespace Common.Utils.TestHelpers.HttpClient
    public class MockHttpClientFactory : IHttpClientFactory
        private readonly MockHttpMessageHandler _mockHttpMessageHandler;
        public MockHttpClientFactory(MockHttpMessageHandler mockHttpMessageHandler)
            _mockHttpMessageHandler = mockHttpMessageHandler ?? throw new ArgumentNullException(nameof(mockHttpMessageHandler));
        public System.Net.Http.HttpClient CreateClient(string name)
            return _mockHttpMessageHandler.ToHttpClient();

Extension:

using RichardSzalay.MockHttp;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
namespace Common.Utils.TestHelpers.HttpClient
    public static class MockHttpMessageHandlerExtensions
        public static IHttpClientFactory ToHttpClientFactory(this MockHttpMessageHandler mockHttpMessageHandler)
            return new MockHttpClientFactory(mockHttpMessageHandler);

Using:

# ...
_apiClientLogic = new ApiClientLogic(_mockHttp.ToHttpClientFactory());
# ...

Regards 😉
Mateusz

Pulling a dependency on IHttpClientFactory would reduce the libraries compatibility with older versions of the framework.

Another approach would be to overwrite individual HttpClient registrations. You add the following to yourWebApplicationFactory

protected override void ConfigureWebHost(IWebHostBuilder builder)
    builder.ConfigureTestServices(services => {  
        var mockHandler = new MockHttpMessageHandler();
        // overwrite the default HttpClient i.e. services.AddHttpClient();
        services.AddHttpClient(string.Empty)
            .ConfigureHttpMessageHandlerBuilder(builder => builder.PrimaryHandler = mockHandler);
        // overwrite a typed client
        services.AddHttpClient<ITypedClient, TypedClient>()
            .ConfigureHttpMessageHandlerBuilder(builder => builder.PrimaryHandler = mockHandler);
    });

This approach also allows you to have a separate mock handler for each HTTP client which would probably make it easier to maintain. I would also make the mock handlers public properties on the WebApplicationFactory so that I could configure the responses on a per test basis.