#229 HttpTest.Settings should always take precedence

This commit is contained in:
Todd Menier 2017-10-03 16:43:10 -05:00
parent 014e5c20fd
commit 22ab91b43a
6 changed files with 74 additions and 24 deletions

View File

@ -261,6 +261,35 @@ namespace Flurl.Test.Http
await Task.WhenAll(tasks); // failed HTTP status, etc, would throw here and fail the test.
}
[Test]
public async Task test_settings_override_client_settings() {
var cli1 = new FlurlClient();
cli1.Settings.HttpClientFactory = new DefaultHttpClientFactory();
var h = cli1.HttpClient; // force (lazy) instantiation
using (var test = new HttpTest()) {
test.Settings.CookiesEnabled = false;
test.RespondWith("foo!");
var s = await cli1.Request("http://www.google.com")
.EnableCookies() // test says cookies are off, and test should always win
.GetStringAsync();
Assert.AreEqual("foo!", s);
Assert.IsFalse(cli1.Settings.CookiesEnabled);
var cli2 = new FlurlClient();
cli2.Settings.HttpClientFactory = new DefaultHttpClientFactory();
h = cli2.HttpClient;
test.RespondWith("foo 2!");
s = await cli2.Request("http://www.google.com")
.EnableCookies() // test says cookies are off, and test should always win
.GetStringAsync();
Assert.AreEqual("foo 2!", s);
Assert.IsFalse(cli2.Settings.CookiesEnabled);
}
}
public class DelegatingHandlerHttpClientFactory : DefaultHttpClientFactory
{
public override HttpMessageHandler CreateMessageHandler() {

View File

@ -179,7 +179,7 @@ namespace Flurl.Test.Http
var rec = "http://www.api.com".EnableCookies();
await rec.GetAsync();
Assert.AreEqual(1, rec.Cookies.Count());
Assert.AreEqual(1, rec.Cookies.Count);
Assert.AreEqual("foo", rec.Cookies["c1"].Value);
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Flurl.Http.Testing;
namespace Flurl.Http.Configuration
{
@ -137,7 +138,9 @@ namespace Flurl.Http.Configuration
/// </summary>
protected T Get<T>(Expression<Func<T>> property) {
var p = (property.Body as MemberExpression).Member as PropertyInfo;
var testVals = HttpTest.Current?.Settings._vals;
return
testVals?.ContainsKey(p.Name) == true ? (T)testVals[p.Name] :
_vals.ContainsKey(p.Name) ? (T)_vals[p.Name] :
_defaults != null ? (T)p.GetValue(_defaults) :
default(T);
@ -206,7 +209,10 @@ namespace Flurl.Http.Configuration
/// Gets or sets the factory that defines creating, caching, and reusing FlurlClient instances and,
/// by proxy, HttpClient instances.
/// </summary>
public IFlurlClientFactory FlurlClientFactory { get; set; }
public IFlurlClientFactory FlurlClientFactory {
get => Get(() => FlurlClientFactory);
set => Set(() => FlurlClientFactory, value);
}
/// <summary>
/// Resets all global settings to their Flurl.Http-defined default values.
@ -214,11 +220,25 @@ namespace Flurl.Http.Configuration
public override void ResetDefaults() {
base.ResetDefaults();
Timeout = TimeSpan.FromSeconds(100); // same as HttpClient
CookiesEnabled = false;
JsonSerializer = new NewtonsoftJsonSerializer(null);
UrlEncodedSerializer = new DefaultUrlEncodedSerializer();
FlurlClientFactory = new PerHostFlurlClientFactory();
HttpClientFactory = new DefaultHttpClientFactory();
}
}
/// <summary>
/// Settings overrides within the context of an HttpTest
/// </summary>
public class TestFlurlHttpSettings : GlobalFlurlHttpSettings
{
/// <summary>
/// Resets all test settings to their Flurl.Http-defined default values.
/// </summary>
public override void ResetDefaults() {
base.ResetDefaults();
FlurlClientFactory = new TestFlurlClientFactory();
HttpClientFactory = new TestHttpClientFactory();
}
}
}

View File

@ -4,6 +4,7 @@ using System.Net;
using System.Net.Http;
using System.Linq;
using Flurl.Http.Configuration;
using Flurl.Http.Testing;
using Flurl.Util;
namespace Flurl.Http
@ -69,10 +70,7 @@ namespace Flurl.Http
BaseUrl = baseUrl;
Settings = new ClientFlurlHttpSettings(FlurlHttp.GlobalSettings);
_httpClient = new Lazy<HttpClient>(() => Settings.HttpClientFactory.CreateHttpClient(HttpMessageHandler));
_httpMessageHandler = new Lazy<HttpMessageHandler>(() => {
_connectionLeaseStart = DateTime.UtcNow;
return Settings.HttpClientFactory.CreateMessageHandler();
});
_httpMessageHandler = new Lazy<HttpMessageHandler>(() => Settings.HttpClientFactory.CreateMessageHandler());
}
/// <inheritdoc />
@ -88,10 +86,10 @@ namespace Flurl.Http
public IDictionary<string, Cookie> Cookies { get; } = new Dictionary<string, Cookie>();
/// <inheritdoc />
public HttpClient HttpClient => _httpClient.Value;
public HttpClient HttpClient => HttpTest.Current?.HttpClient ?? _httpClient.Value;
/// <inheritdoc />
public HttpMessageHandler HttpMessageHandler => _httpMessageHandler.Value;
public HttpMessageHandler HttpMessageHandler => HttpTest.Current?.HttpMessageHandler ?? _httpMessageHandler.Value;
/// <inheritdoc />
public IFlurlRequest Request(params object[] urlSegments) {
@ -112,13 +110,12 @@ namespace Flurl.Http
set => Settings = value as ClientFlurlHttpSettings;
}
private DateTime? _connectionLeaseStart = null;
private Lazy<DateTime> _connectionLeaseStart = new Lazy<DateTime>(() => DateTime.UtcNow);
private readonly object _connectionLeaseLock = new object();
private bool IsConnectionLeaseExpired =>
_connectionLeaseStart.HasValue &&
Settings.ConnectionLeaseTimeout.HasValue &&
DateTime.UtcNow - _connectionLeaseStart > Settings.ConnectionLeaseTimeout;
DateTime.UtcNow - _connectionLeaseStart.Value > Settings.ConnectionLeaseTimeout;
/// <inheritdoc />
public bool CheckAndRenewConnectionLease() {
@ -126,7 +123,7 @@ namespace Flurl.Http
if (IsConnectionLeaseExpired) {
lock (_connectionLeaseLock) {
if (IsConnectionLeaseExpired) {
_connectionLeaseStart = DateTime.UtcNow;
_connectionLeaseStart = new Lazy<DateTime>(() => DateTime.UtcNow);
return true;
}
}

View File

@ -1,6 +1,5 @@
using System;
using Flurl.Http.Configuration;
using Flurl.Http.Testing;
namespace Flurl.Http
{
@ -17,7 +16,7 @@ namespace Flurl.Http
/// <summary>
/// Globally configured Flurl.Http settings. Should normally be written to by calling FlurlHttp.Configure once application at startup.
/// </summary>
public static GlobalFlurlHttpSettings GlobalSettings => HttpTest.Current?.Settings ?? _settings.Value;
public static GlobalFlurlHttpSettings GlobalSettings => _settings.Value;
/// <summary>
/// Provides thread-safe access to Flurl.Http's global configuration settings. Should only be called once at application startup.

View File

@ -15,20 +15,25 @@ namespace Flurl.Http.Testing
/// </summary>
public class HttpTest : IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="HttpTest"/> class.
/// </summary>
/// <exception cref="Exception">A delegate callback throws an exception.</exception>
public HttpTest() {
Settings = new GlobalFlurlHttpSettings {
HttpClientFactory = new TestHttpClientFactory(),
FlurlClientFactory = new TestFlurlClientFactory()
};
private readonly Lazy<HttpClient> _httpClient;
private readonly Lazy<HttpMessageHandler> _httpMessageHandler;
/// <summary>
/// Initializes a new instance of the <see cref="HttpTest"/> class.
/// </summary>
/// <exception cref="Exception">A delegate callback throws an exception.</exception>
public HttpTest() {
Settings = new TestFlurlHttpSettings();
ResponseQueue = new Queue<HttpResponseMessage>();
CallLog = new List<HttpCall>();
_httpClient = new Lazy<HttpClient>(() => Settings.HttpClientFactory.CreateHttpClient(HttpMessageHandler));
_httpMessageHandler = new Lazy<HttpMessageHandler>(() => Settings.HttpClientFactory.CreateMessageHandler());
SetCurrentTest(this);
}
internal HttpClient HttpClient => _httpClient.Value;
internal HttpMessageHandler HttpMessageHandler => _httpMessageHandler.Value;
/// <summary>
/// Gets or sets the FlurlHttpSettings object used by this test.
/// </summary>