Skip to content

Commit 2c3a7d0

Browse files
committed
Add the ability to set the JsonSerializerOptions
1 parent a7979de commit 2c3a7d0

21 files changed

+310
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1515
- `CreateClient` now accepts `DelegateHandlers` in order to chain Handlers. The InnerHandler property of each handler is set automatically and the `TestableHttpMessageHandler` is automatically set as the last handler. This is showcased with Polly in the integration tests.
1616
- Added support for .NET Framework 4.6.2, .NET Framework 4.7 and .NET Framework 4.8 by running the tests against these versions.
1717
- Added several `Responses`, including `Delayed`, `Timeout`, `Configured`, `Sequenced`, `StatusCode` and `Json`. These responses can now be used inside the `RespondWith`.
18+
- Added the possibility to set and override the JsonSerializerOptions.
1819

1920
### Changed
2021
- `TestableHttpClient` now works with the `Responses` class, making it easier to configure responses.

src/TestableHttpClient.NFluent/FluentHttpRequestMessagesChecks.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ internal class FluentHttpRequestMessagesChecks : FluentSut<IEnumerable<HttpReque
88
private IEnumerable<HttpRequestMessage> requests;
99
private readonly List<string> requestConditions = new List<string>();
1010

11-
public FluentHttpRequestMessagesChecks(IEnumerable<HttpRequestMessage> httpRequestMessages)
11+
public FluentHttpRequestMessagesChecks(IEnumerable<HttpRequestMessage> httpRequestMessages, TestableHttpMessageHandlerOptions? options = null)
1212
: base(httpRequestMessages, Check.Reporter, false)
1313
{
1414
requests = httpRequestMessages ?? throw new ArgumentNullException(nameof(httpRequestMessages));
15+
Options = options ?? new TestableHttpMessageHandlerOptions();
1516
}
1617

18+
public TestableHttpMessageHandlerOptions Options { get; }
19+
1720
public IHttpRequestMessagesCheck WithFilter(Func<HttpRequestMessage, bool> requestFilter, string condition) => WithFilter(requestFilter, null, condition);
1821

1922
public IHttpRequestMessagesCheck WithFilter(Func<HttpRequestMessage, bool> requestFilter, int expectedNumberOfRequests, string condition) => WithFilter(requestFilter, (int?)expectedNumberOfRequests, condition);

src/TestableHttpClient/HttpRequestMessageAsserter.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ internal class HttpRequestMessageAsserter : IHttpRequestMessagesCheck
1111
/// Construct a new HttpRequestMessageAsserter.
1212
/// </summary>
1313
/// <param name="httpRequestMessages">The list of requests to assert on.</param>
14-
public HttpRequestMessageAsserter(IEnumerable<HttpRequestMessage> httpRequestMessages)
14+
/// <param name="options">Options that could be used by several assertions.</param>
15+
public HttpRequestMessageAsserter(IEnumerable<HttpRequestMessage> httpRequestMessages, TestableHttpMessageHandlerOptions? options = null)
1516
{
1617
Requests = httpRequestMessages ?? throw new ArgumentNullException(nameof(httpRequestMessages));
18+
Options = options ?? new TestableHttpMessageHandlerOptions();
1719
}
1820

1921
/// <summary>
2022
/// The list of requests received from <seealso cref="TestableHttpMessageHandler"/>.
2123
/// </summary>
2224
public IEnumerable<HttpRequestMessage> Requests { get; private set; }
25+
/// <summary>
26+
/// Options that could be used by several assertions.
27+
/// </summary>
28+
public TestableHttpMessageHandlerOptions Options { get; }
2329

2430
private void Assert(int? expectedCount = null)
2531
{

src/TestableHttpClient/HttpRequestMessagesCheckExtensions.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,26 @@ private static IHttpRequestMessagesCheck WithContent(this IHttpRequestMessagesCh
405405
/// <param name="jsonObject">The object representation of the expected request content.</param>
406406
/// <returns>The <seealso cref="IHttpRequestMessagesCheck"/> for further assertions.</returns>
407407
/// <remarks>Note that on .NET Framework, the HttpClient might dispose the content after sending the request.</remarks>
408-
public static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject) => WithJsonContent(check, jsonObject, null);
408+
public static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject) => WithJsonContent(check, jsonObject, null, null);
409+
410+
/// <summary>
411+
/// Asserts wheter requests are made with specific json content.
412+
/// </summary>
413+
/// <param name="check">The implementation that hold all the request messages.</param>
414+
/// <param name="jsonObject">The object representation of the expected request content.</param>
415+
/// <returns>The <seealso cref="IHttpRequestMessagesCheck"/> for further assertions.</returns>
416+
/// <remarks>Note that on .NET Framework, the HttpClient might dispose the content after sending the request.</remarks>
417+
public static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject, JsonSerializerOptions jsonSerializerOptions) => WithJsonContent(check, jsonObject, jsonSerializerOptions, null);
418+
419+
/// <summary>
420+
/// Asserts wheter requests are made with specific json content.
421+
/// </summary>
422+
/// <param name="check">The implementation that hold all the request messages.</param>
423+
/// <param name="jsonObject">The object representation of the expected request content.</param>
424+
/// <param name="expectedNumberOfRequests">The expected number of requests.</param>
425+
/// <returns>The <seealso cref="IHttpRequestMessagesCheck"/> for further assertions.</returns>
426+
/// <remarks>Note that on .NET Framework, the HttpClient might dispose the content after sending the request.</remarks>
427+
public static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject, int expectedNumberOfRequests) => WithJsonContent(check, jsonObject, null, (int?)expectedNumberOfRequests);
409428

410429
/// <summary>
411430
/// Asserts wheter requests are made with specific json content.
@@ -415,16 +434,16 @@ private static IHttpRequestMessagesCheck WithContent(this IHttpRequestMessagesCh
415434
/// <param name="expectedNumberOfRequests">The expected number of requests.</param>
416435
/// <returns>The <seealso cref="IHttpRequestMessagesCheck"/> for further assertions.</returns>
417436
/// <remarks>Note that on .NET Framework, the HttpClient might dispose the content after sending the request.</remarks>
418-
public static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject, int expectedNumberOfRequests) => WithJsonContent(check, jsonObject, (int?)expectedNumberOfRequests);
437+
public static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject, JsonSerializerOptions jsonSerializerOptions, int expectedNumberOfRequests) => WithJsonContent(check, jsonObject, jsonSerializerOptions, (int?)expectedNumberOfRequests);
419438

420-
private static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject, int? expectedNumberOfRequests)
439+
private static IHttpRequestMessagesCheck WithJsonContent(this IHttpRequestMessagesCheck check, object? jsonObject, JsonSerializerOptions? jsonSerializerOptions, int? expectedNumberOfRequests)
421440
{
422441
if (check == null)
423442
{
424443
throw new ArgumentNullException(nameof(check));
425444
}
426445

427-
var jsonString = JsonSerializer.Serialize(jsonObject);
446+
var jsonString = JsonSerializer.Serialize(jsonObject, jsonSerializerOptions ?? check.Options.JsonSerializerOptions);
428447
return check.WithFilter(x => x.HasContent(jsonString) && x.HasContentHeader("Content-Type", "application/json*"), expectedNumberOfRequests, $"json content '{jsonString}'");
429448
}
430449

src/TestableHttpClient/HttpResponseContext.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
/// </summary>
66
public class HttpResponseContext
77
{
8-
public HttpResponseContext(HttpRequestMessage httpRequestMessage, HttpResponseMessage httpResponseMessage)
8+
public HttpResponseContext(HttpRequestMessage httpRequestMessage, HttpResponseMessage httpResponseMessage, TestableHttpMessageHandlerOptions? options = null)
99
{
1010
HttpRequestMessage = httpRequestMessage;
1111
HttpResponseMessage = httpResponseMessage;
12+
Options = options ?? new TestableHttpMessageHandlerOptions();
1213
}
1314

1415
/// <summary>
@@ -19,4 +20,5 @@ public HttpResponseContext(HttpRequestMessage httpRequestMessage, HttpResponseMe
1920
/// The response message that will be send back to the HttpClient.
2021
/// </summary>
2122
public HttpResponseMessage HttpResponseMessage { get; }
23+
public TestableHttpMessageHandlerOptions Options { get; }
2224
}

src/TestableHttpClient/IHttpRequestMessagesCheck.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
/// </summary>
66
public interface IHttpRequestMessagesCheck
77
{
8+
/// <summary>
9+
/// Options that could be used by several asserters.
10+
/// </summary>
11+
TestableHttpMessageHandlerOptions Options { get; }
12+
813
/// <summary>
914
/// Asserts whether requests comply with a specific filter.
1015
/// </summary>

src/TestableHttpClient/Response/JsonResponse.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ public JsonResponse(object? content, string? contentType = null)
1010

1111
public object? Content { get; }
1212
public string ContentType { get; }
13+
public JsonSerializerOptions? JsonSerializerOptions { get; set; }
1314

1415
protected override Task<HttpContent?> GetContentAsync(HttpResponseContext context, CancellationToken cancellationToken)
1516
{
16-
string json = JsonSerializer.Serialize(Content);
17+
string json = JsonSerializer.Serialize(Content, JsonSerializerOptions ?? context.Options.JsonSerializerOptions);
1718
return Task.FromResult<HttpContent?>(new StringContent(json, Encoding.UTF8, ContentType));
1819
}
1920
}

src/TestableHttpClient/Responses.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ public static class Responses
7070
/// <param name="content">The content to serialize.</param>
7171
/// <param name="contentType">The content type of the response, defaults to 'application/json'.</param>
7272
/// <returns>A response with specific content.</returns>
73-
public static IResponse Json(object? content, string? contentType = null) => new JsonResponse(content, contentType);
73+
public static IResponse Json(object? content, string? contentType = null, JsonSerializerOptions? jsonSerializerOptions = null) => new JsonResponse(content, contentType) { JsonSerializerOptions = jsonSerializerOptions };
7474
/// <summary>
7575
/// Create a response with json content and a specific status code.
7676
/// </summary>
7777
/// <param name="content">The content to serialize.</param>
7878
/// <param name="statusCode">The status code for the response.</param>
7979
/// <param name="contentType">The content type of the response, defaults to 'application/json'.</param>
8080
/// <returns>A response with specific content.</returns>
81-
public static IResponse Json(object? content, HttpStatusCode statusCode, string? contentType = null) => new JsonResponse(content, contentType) { StatusCode = statusCode };
81+
public static IResponse Json(object? content, HttpStatusCode statusCode, string? contentType = null, JsonSerializerOptions? jsonSerializerOptions = null) => new JsonResponse(content, contentType) { StatusCode = statusCode, JsonSerializerOptions = jsonSerializerOptions };
8282
/// <summary>
8383
/// Entrypoint for extensions.
8484
/// </summary>

src/TestableHttpClient/TestableHttpMessageHandler.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class TestableHttpMessageHandler : HttpMessageHandler
1212
private IResponse response = new HttpResponse(HttpStatusCode.OK);
1313
private Func<HttpRequestMessage, HttpResponseMessage>? responseFactory;
1414

15+
public TestableHttpMessageHandlerOptions Options { get; } = new TestableHttpMessageHandlerOptions();
16+
1517
/// <summary>
1618
/// Gets the collection of captured requests made using this HttpMessageHandler.
1719
/// </summary>
@@ -29,7 +31,7 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
2931
else
3032
{
3133
responseMessage = new();
32-
HttpResponseContext context = new(request, responseMessage);
34+
HttpResponseContext context = new(request, responseMessage, Options);
3335
await response.ExecuteAsync(context, cancellationToken).ConfigureAwait(false);
3436
}
3537

src/TestableHttpClient/TestableHttpMessageHandlerAssertionExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static IHttpRequestMessagesCheck ShouldHaveMadeRequests(this TestableHttp
1717
throw new ArgumentNullException(nameof(handler));
1818
}
1919

20-
return new HttpRequestMessageAsserter(handler.Requests).WithRequestUri("*");
20+
return new HttpRequestMessageAsserter(handler.Requests, handler.Options).WithRequestUri("*");
2121
}
2222

2323
/// <summary>
@@ -36,7 +36,7 @@ public static IHttpRequestMessagesCheck ShouldHaveMadeRequests(this TestableHttp
3636
throw new ArgumentNullException(nameof(handler));
3737
}
3838

39-
return new HttpRequestMessageAsserter(handler.Requests).WithRequestUri("*", expectedNumberOfRequests);
39+
return new HttpRequestMessageAsserter(handler.Requests, handler.Options).WithRequestUri("*", expectedNumberOfRequests);
4040
}
4141

4242
/// <summary>
@@ -60,7 +60,7 @@ public static IHttpRequestMessagesCheck ShouldHaveMadeRequestsTo(this TestableHt
6060
throw new ArgumentNullException(nameof(pattern));
6161
}
6262

63-
return new HttpRequestMessageAsserter(handler.Requests).WithRequestUri(pattern);
63+
return new HttpRequestMessageAsserter(handler.Requests, handler.Options).WithRequestUri(pattern);
6464
}
6565

6666
/// <summary>
@@ -85,6 +85,6 @@ public static IHttpRequestMessagesCheck ShouldHaveMadeRequestsTo(this TestableHt
8585
throw new ArgumentNullException(nameof(pattern));
8686
}
8787

88-
return new HttpRequestMessageAsserter(handler.Requests).WithRequestUri(pattern, expectedNumberOfRequests);
88+
return new HttpRequestMessageAsserter(handler.Requests, handler.Options).WithRequestUri(pattern, expectedNumberOfRequests);
8989
}
9090
}

0 commit comments

Comments
 (0)