I'm using the OWIN TestServer which provides me an HttpClient to do my in memory calls to the test server. I'm wondering if there's a way of passing in the existing HttpClient for Flurl to use.
问题:
回答1:
UPDATE: Much of the information below is no longer relevant in Flurl.Http 2.x. Specifically, most of Flurl's functionality is contained in the new FlurlClient
object (which wraps HttpClient
) and not in a custom message handler, so you're not losing functionality if you provide a different HttpClient
. Further, as of Flurl.Http 2.3.1, you no longer need a custom factory to do this. It's as easy as:
var flurlClient = new FlurlClient(httpClient);
Flurl provides an IHttpClientFactory
interface that allows you to customize HttpClient
construction. However, much of Flurl's functionality is provided by a custom HttpMessageHandler
, which is added to HttpClient
on construction. You wouldn't want to hot-swap it out for an already instantiated HttpClient
or you'll risk breaking Flurl.
Fortunately, OWIN TestServer is also driven by an HttpMessageHandler
, and you can pipeline multiple when you create an HttpClient
.
Start with a custom factory that allows you to pass in the TestServer
instance:
using Flurl.Http.Configuration;
using Microsoft.Owin.Testing;
public class OwinTestHttpClientFactory : DefaultHttpClientFactory
{
private readonly TestServer _testServer;
public OwinTestHttpClientFactory(TestServer server) {
_testServer = server;
}
public override HttpMessageHandler CreateMessageHandler() {
// TestServer's HttpMessageHandler will be added to the end of the pipeline
return _testServer.Handler;
}
}
Factories can be registered globally, but since you need a different TestServer
instance for each test, I'd recommend setting it on the FlurlClient
instance, which is a new capability as of Flurl.Http 0.7. So your tests would look something like this:
using (var testServer = TestServer.Create(...)) {
using (var flurlClient = new FlurlClient()) {
flurlClient.Settings.HttpClientFactory = new OwinTestHttpClientFactory(testServer);
// do your tests with the FlurlClient instance. 2 ways to do that:
url.WithClient(flurlClient).PostJsonAsync(...);
flurlClient.WithUrl(url).PostJsonAsync(...);
}
}