diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index a352993..e7096cd 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "nbgv": { - "version": "3.7.112", + "version": "3.7.115", "commands": [ "nbgv" ], diff --git a/CHANGELOG.md b/CHANGELOG.md index 7240575..958c300 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [0.12] - unplanned ### Removed - .NET 6.0 target, since it is no longer supported +- .NET Framework 4.6.2, 4.7.0 and 4.7.2, since these can't be tested using xUnit v3 ### Added - Support for .NET 9.0 diff --git a/README.md b/README.md index d50e42d..157bb5f 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,7 @@ The options include: TestableHttpClient is build as a netstandard2.0 library, so theoretically it can work on every .NET version that support netstandard2.0. The following versions are being actively tested and thus supported: -- .NET Framework 4.6, 4.7 and 4.8 -- .NET 6.0 +- .NET Framework 4.7.2 and 4.8 - .NET 8.0 - .NET 9.0 diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 4c9b869..6348ff4 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,8 +1,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/TestableHttpClient.IntegrationTests/AssertingRequests.cs b/test/TestableHttpClient.IntegrationTests/AssertingRequests.cs index a1c2122..26875f8 100644 --- a/test/TestableHttpClient.IntegrationTests/AssertingRequests.cs +++ b/test/TestableHttpClient.IntegrationTests/AssertingRequests.cs @@ -18,7 +18,7 @@ public async Task WhenAssertingCallsAreNotMade_AndCallsWereMade_AssertionExcepti using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequests(); Assert.Throws(() => testHandler.ShouldHaveMadeRequests(0)); @@ -30,7 +30,7 @@ public async Task AssertingCallsAreNotMadeToSpecificUri() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequestsTo("https://example.org", 0); Assert.Throws(() => testHandler.ShouldHaveMadeRequestsTo("https://httpbin.org/get", 0)); @@ -42,7 +42,7 @@ public async Task AssertingCallsAreMadeToSpecificUriPattern() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequestsTo("https://*"); testHandler.ShouldHaveMadeRequestsTo("https://*.org/get"); @@ -61,7 +61,7 @@ public async Task AssertingCallsUsingUriPattern() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequests().WithRequestUri("https://*"); testHandler.ShouldHaveMadeRequests().WithRequestUri("https://*.org/get"); @@ -80,7 +80,7 @@ public async Task ChainUriPatternAssertions() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequestsTo("https://*") .WithRequestUri("*://httpbin.org/*") @@ -93,7 +93,7 @@ public async Task AssertingCallWithQueryParameters() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get?email=admin@example.com"); + _ = await client.GetAsync("https://httpbin.org/get?email=admin@example.com", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequests().WithRequestUri("?email=admin@example.com"); testHandler.ShouldHaveMadeRequests().WithRequestUri("?email=*"); @@ -106,9 +106,9 @@ public async Task AssertingHttpMethods() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); using StringContent content = new(""); - _ = await client.PostAsync("https://httpbin.org/post", content); + _ = await client.PostAsync("https://httpbin.org/post", content, TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequestsTo("*/get").WithHttpMethod(HttpMethod.Get); Assert.Throws(() => testHandler.ShouldHaveMadeRequestsTo("*/get").WithHttpMethod(HttpMethod.Post)); @@ -122,7 +122,7 @@ public async Task AssertingRequestHeaders() using TestableHttpMessageHandler testHandler = new(); using HttpClient client = new(testHandler); client.DefaultRequestHeaders.Add("api-version", "1.0"); - _ = await client.GetAsync("https://httpbin.org/get"); + _ = await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequests().WithRequestHeader("api-version"); testHandler.ShouldHaveMadeRequests().WithRequestHeader("api-version", "1.0"); @@ -140,7 +140,7 @@ public async Task AssertingContentHeaders() using HttpClient client = new(testHandler); using StringContent content = new("", Encoding.UTF8, "application/json"); - _ = await client.PostAsync("https://httpbin.org/post", content); + _ = await client.PostAsync("https://httpbin.org/post", content, TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequests().WithContentHeader("content-type"); testHandler.ShouldHaveMadeRequests().WithContentHeader("Content-Type"); @@ -160,7 +160,7 @@ public async Task AssertingContent() using HttpClient client = new(testHandler); using StringContent content = new("my special content"); - _ = await client.PostAsync("https://httpbin.org/post", content); + _ = await client.PostAsync("https://httpbin.org/post", content, TestContext.Current.CancellationToken); #if NETFRAMEWORK // On .NET Framework the HttpClient disposes the content automatically. So we can't perform the same test. @@ -182,7 +182,7 @@ public async Task AssertJsonContent() using HttpClient client = new(testHandler); using StringContent content = new("{}", Encoding.UTF8, "application/json"); - _ = await client.PostAsync("https://httpbin.org/post", content); + _ = await client.PostAsync("https://httpbin.org/post", content, TestContext.Current.CancellationToken); #if NETFRAMEWORK // On .NET Framework the HttpClient disposes the content automatically. So we can't perform the same test. @@ -199,7 +199,7 @@ public async Task CustomAssertions() using HttpClient client = new(testHandler); using StringContent content = new("", Encoding.UTF8, "application/json"); - _ = await client.PostAsync("https://httpbin.org/post", content); + _ = await client.PostAsync("https://httpbin.org/post", content, TestContext.Current.CancellationToken); testHandler.ShouldHaveMadeRequests().WithFilter(x => x.Content is not null && x.Content.Headers.ContentType?.MediaType == "application/json", ""); } diff --git a/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs b/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs index fdfcce1..17e5e89 100644 --- a/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs +++ b/test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs @@ -10,10 +10,10 @@ public async Task UsingTestHandler_WithoutSettingUpResponse_Returns200OKWithoutC using TestableHttpMessageHandler testHandler = new(); using HttpClient httpClient = new(testHandler); - HttpResponseMessage result = await httpClient.GetAsync("http://httpbin.org/status/200"); + HttpResponseMessage result = await httpClient.GetAsync("http://httpbin.org/status/200", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(string.Empty, await result.Content.ReadAsStringAsync()); + Assert.Equal(string.Empty, await result.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); } [Fact] @@ -23,10 +23,10 @@ public async Task UsingTestHandlerWithCustomResponse_ReturnsCustomResponse() testHandler.RespondWith(Text("HttpClient testing is easy")); using HttpClient httpClient = new(testHandler); - HttpResponseMessage result = await httpClient.GetAsync("http://httpbin.org/status/200"); + HttpResponseMessage result = await httpClient.GetAsync("http://httpbin.org/status/200", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal("HttpClient testing is easy", await result.Content.ReadAsStringAsync()); + Assert.Equal("HttpClient testing is easy", await result.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); } [Fact] @@ -37,10 +37,10 @@ public async Task UsingTestHandlerWithMultipleCustomResponse_ReturnsLastCustomRe testHandler.RespondWith(Json("Not Found", HttpStatusCode.NotFound)); using HttpClient httpClient = new(testHandler); - HttpResponseMessage result = await httpClient.GetAsync("http://httpbin.org/status/201"); + HttpResponseMessage result = await httpClient.GetAsync("http://httpbin.org/status/201", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, result.StatusCode); - Assert.Equal("\"Not Found\"", await result.Content.ReadAsStringAsync()); + Assert.Equal("\"Not Found\"", await result.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); } [Fact] @@ -60,10 +60,10 @@ public async Task UsingTestHandlerWithCustomResponse_AlwaysReturnsSameCustomResp foreach (string? url in urls) { - HttpResponseMessage result = await httpClient.GetAsync(url); + HttpResponseMessage result = await httpClient.GetAsync(url, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal("HttpClient testing is easy", await result.Content.ReadAsStringAsync()); + Assert.Equal("HttpClient testing is easy", await result.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); } } @@ -85,13 +85,13 @@ static IResponse PathBasedResponse(HttpResponseContext context) testHandler.RespondWith(SelectResponse(PathBasedResponse)); using HttpClient httpClient = new(testHandler); - HttpResponseMessage response = await httpClient.GetAsync("http://httpbin/status/200"); + HttpResponseMessage response = await httpClient.GetAsync("http://httpbin/status/200", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - response = await httpClient.GetAsync("http://httpbin.org/status/400"); + response = await httpClient.GetAsync("http://httpbin.org/status/400", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - response = await httpClient.GetAsync("http://httpbin.org/status/500"); + response = await httpClient.GetAsync("http://httpbin.org/status/500", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } @@ -108,16 +108,16 @@ public async Task UsingTestHandlerWithRoute_AllowsForRoutingUseCases() })); using HttpClient httpClient = new(testHandler); - HttpResponseMessage response = await httpClient.GetAsync("http://httpbin/status/200"); + HttpResponseMessage response = await httpClient.GetAsync("http://httpbin/status/200", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.Redirect, response.StatusCode); - response = await httpClient.GetAsync("https://httpbin/status/200"); + response = await httpClient.GetAsync("https://httpbin/status/200", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - response = await httpClient.GetAsync("https://httpbin.org/status/400"); + response = await httpClient.GetAsync("https://httpbin.org/status/400", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); - response = await httpClient.GetAsync("https://httpbin.org/status/500"); + response = await httpClient.GetAsync("https://httpbin.org/status/500", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } @@ -128,7 +128,7 @@ public async Task SimulateTimeout_WillThrowExceptionSimulatingTheTimeout() testHandler.RespondWith(Timeout()); using HttpClient httpClient = new(testHandler); - await Assert.ThrowsAsync(() => httpClient.GetAsync("https://httpbin.org/delay/500")); + await Assert.ThrowsAsync(() => httpClient.GetAsync("https://httpbin.org/delay/500", TestContext.Current.CancellationToken)); } [Fact] @@ -143,20 +143,20 @@ public async Task UsingTestHandlerWithSequencedResponses_WillReturnDifferentResp )); using HttpClient httpClient = new(testHandler); - HttpResponseMessage response = await httpClient.GetAsync("http://httpbin.org/anything"); + HttpResponseMessage response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - response = await httpClient.GetAsync("http://httpbin.org/anything"); + response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); - response = await httpClient.GetAsync("http://httpbin.org/anything"); + response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); - response = await httpClient.GetAsync("http://httpbin.org/anything"); + response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); // Last configured response is returned when all other responses are used. - response = await httpClient.GetAsync("http://httpbin.org/anything"); + response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } @@ -167,7 +167,7 @@ public async Task UsingTestHandlerWithDelayedResponses_WillDelayTheResponse() testHandler.RespondWith(Delayed(StatusCode(HttpStatusCode.OK), TimeSpan.FromSeconds(1))); using HttpClient httpClient = new(testHandler); - HttpResponseMessage response = await httpClient.GetAsync("http://httpbin.org/anything"); + HttpResponseMessage response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, response.StatusCode); } @@ -178,7 +178,7 @@ public async Task UsingTestHandlerWithConfiguredResponses_WillConfigureTheRespon testHandler.RespondWith(Configured(StatusCode(HttpStatusCode.NoContent), x => x.Headers.Add("server", "test"))); using HttpClient httpClient = new(testHandler); - HttpResponseMessage response = await httpClient.GetAsync("http://httpbin.org/anything"); + HttpResponseMessage response = await httpClient.GetAsync("http://httpbin.org/anything", TestContext.Current.CancellationToken); Assert.Equal("test", response.Headers.Server.ToString()); } } diff --git a/test/TestableHttpClient.IntegrationTests/CreatingClients.cs b/test/TestableHttpClient.IntegrationTests/CreatingClients.cs index d9fb655..a22aab6 100644 --- a/test/TestableHttpClient.IntegrationTests/CreatingClients.cs +++ b/test/TestableHttpClient.IntegrationTests/CreatingClients.cs @@ -10,7 +10,7 @@ public async Task CreateASimpleHttpClient() using TestableHttpMessageHandler testableHttpMessageHandler = new(); using HttpClient client = testableHttpMessageHandler.CreateClient(); - await client.GetAsync("https://httpbin.org/get"); + await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testableHttpMessageHandler.ShouldHaveMadeRequestsTo("https://httpbin.org/get"); } @@ -21,7 +21,7 @@ public async Task CreateClientWithConfiguration() using TestableHttpMessageHandler testableHttpMessageHandler = new(); using HttpClient client = testableHttpMessageHandler.CreateClient(client => client.DefaultRequestHeaders.Add("test", "test")); - await client.GetAsync("https://httpbin.org/get"); + await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testableHttpMessageHandler.ShouldHaveMadeRequests().WithRequestHeader("test", "test"); } @@ -33,7 +33,7 @@ public async Task CreateClientWithCustomHandlers() using TestHandler handler = new(); using HttpClient client = testableHttpMessageHandler.CreateClient(handler); - await client.GetAsync("https://httpbin.org/get"); + await client.GetAsync("https://httpbin.org/get", TestContext.Current.CancellationToken); testableHttpMessageHandler.ShouldHaveMadeRequestsTo("https://httpbin.org/get"); Assert.True(handler.WasCalled); diff --git a/test/TestableHttpClient.IntegrationTests/CustomizeJsonSerialization.cs b/test/TestableHttpClient.IntegrationTests/CustomizeJsonSerialization.cs index a2ce9fa..5c852b0 100644 --- a/test/TestableHttpClient.IntegrationTests/CustomizeJsonSerialization.cs +++ b/test/TestableHttpClient.IntegrationTests/CustomizeJsonSerialization.cs @@ -49,7 +49,7 @@ public async Task Asserting_also_works_this_way() { using TestableHttpMessageHandler sut = new(); using HttpClient client = sut.CreateClient(); - await client.PostAsJsonAsync("http://localhost", new { Name = "Charlie" }); + await client.PostAsJsonAsync("http://localhost", new { Name = "Charlie" }, cancellationToken: TestContext.Current.CancellationToken); #if NETFRAMEWORK // Well this doesn't really work on .NET Framework. @@ -70,7 +70,7 @@ public async Task And_we_can_go_crazy_with_it() WriteIndented = true }; - await client.PostAsJsonAsync("http://localhost", new { Name = "Charlie" }, options); + await client.PostAsJsonAsync("http://localhost", new { Name = "Charlie" }, options, cancellationToken: TestContext.Current.CancellationToken); #if NETFRAMEWORK // Well this doesn't really work on .NET Framework. diff --git a/test/TestableHttpClient.IntegrationTests/NetFrameworkPollyFill.cs b/test/TestableHttpClient.IntegrationTests/NetFrameworkPollyFill.cs new file mode 100644 index 0000000..2d036e7 --- /dev/null +++ b/test/TestableHttpClient.IntegrationTests/NetFrameworkPollyFill.cs @@ -0,0 +1,15 @@ +using System.Threading; + +namespace TestableHttpClient.IntegrationTests; + +#if NETFRAMEWORK + +internal static class NetFrameworkPollyFill +{ + public static Task ReadAsStringAsync(this HttpContent content, CancellationToken cancellationToken = default) + { + return content.ReadAsStringAsync(); + } +} + +#endif diff --git a/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj b/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj index 9f5f726..2053fe0 100644 --- a/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj +++ b/test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj @@ -1,7 +1,8 @@  - net462;net47;net48;net8.0;net9.0 + net472;net48;net8.0;net9.0 + Exe diff --git a/test/TestableHttpClient.IntegrationTests/TestingRetryMechanisms.cs b/test/TestableHttpClient.IntegrationTests/TestingRetryMechanisms.cs index 09c8f32..570b76e 100644 --- a/test/TestableHttpClient.IntegrationTests/TestingRetryMechanisms.cs +++ b/test/TestableHttpClient.IntegrationTests/TestingRetryMechanisms.cs @@ -30,7 +30,7 @@ public async Task TestingRetryPolicies() using HttpClient client = testableHttpMessageHandler.CreateClient(retryPolicyHandler); // Make a request, which should pass - HttpResponseMessage response = await client.GetAsync("https://httpbin.com/get"); + HttpResponseMessage response = await client.GetAsync("https://httpbin.com/get", TestContext.Current.CancellationToken); // Now use the assertions to make sure the request was actually made multiple times. _ = testableHttpMessageHandler.ShouldHaveMadeRequestsTo("https://httpbin.com/get", 3); @@ -53,7 +53,7 @@ public void SimulateTimeoutDoesNotRetry() using HttpClient client = testableHttpMessageHandler.CreateClient(retryPolicyHandler); - Task task = client.GetAsync("https://httpbin.com/get"); + Task task = client.GetAsync("https://httpbin.com/get", TestContext.Current.CancellationToken); Assert.True(task.IsCanceled); // Now use the assertions to make sure the request was actually made once, so polly didn't run. diff --git a/test/TestableHttpClient.IntegrationTests/UsingIHttpClientFactory.cs b/test/TestableHttpClient.IntegrationTests/UsingIHttpClientFactory.cs index 2ef63c1..36c93df 100644 --- a/test/TestableHttpClient.IntegrationTests/UsingIHttpClientFactory.cs +++ b/test/TestableHttpClient.IntegrationTests/UsingIHttpClientFactory.cs @@ -29,7 +29,7 @@ public async Task ConfigureIHttpClientFactoryToUseTestableHttpClient() // Create the HttpClient using HttpClient client = httpClientFactory.CreateClient(); // And use it... - _ = await client.GetAsync("https://httpbin.com/get"); + _ = await client.GetAsync("https://httpbin.com/get", TestContext.Current.CancellationToken); // Now use the assertions to make sure the request was actually made. testableHttpMessageHandler.ShouldHaveMadeRequestsTo("https://httpbin.com/get"); @@ -63,14 +63,14 @@ public async Task ConfigureMultipleHttpMessageHandlers() // Create the named HttpClient using HttpClient githubClient = httpClientFactory.CreateClient("github"); // And use it. - HttpResponseMessage result = await githubClient.GetAsync("https://github.com/api/users"); + HttpResponseMessage result = await githubClient.GetAsync("https://github.com/api/users", TestContext.Current.CancellationToken); Assert.Equal("github", result.Headers.Server.ToString()); Assert.Equal(HttpStatusCode.OK, result.StatusCode); // Create another named HttpClient using HttpClient httpbinClient = httpClientFactory.CreateClient("httpbin"); // And use it... - result = await httpbinClient.GetAsync("https://httpbin.com/get"); + result = await httpbinClient.GetAsync("https://httpbin.com/get", TestContext.Current.CancellationToken); Assert.Equal("httpbin", result.Headers.Server.ToString()); Assert.Equal(HttpStatusCode.NotFound, result.StatusCode); @@ -96,11 +96,11 @@ public async Task ConfigureViaConfigureTestServicesOnHostBuilder() // Reconfigure the default HttpClient and set the TestableHttpMessageHandler as the primary HttpMessageHandler .ConfigureTestServices(services => services.AddHttpClient(string.Empty).ConfigurePrimaryHttpMessageHandler(() => testableHttpMessageHandler)); }) - .StartAsync(); + .StartAsync(cancellationToken: TestContext.Current.CancellationToken); using HttpClient client = host.GetTestClient(); // Make a request to the testserver - _ = await client.GetAsync("/"); + _ = await client.GetAsync("/", TestContext.Current.CancellationToken); // Assert that the code in the test server made the expected request. testableHttpMessageHandler.ShouldHaveMadeRequestsTo("https://httpbin.com/get"); diff --git a/test/TestableHttpClient.Tests/NetFrameworkPollyFill.cs b/test/TestableHttpClient.Tests/NetFrameworkPollyFill.cs new file mode 100644 index 0000000..1823f11 --- /dev/null +++ b/test/TestableHttpClient.Tests/NetFrameworkPollyFill.cs @@ -0,0 +1,15 @@ +#if NETFRAMEWORK +using System.Threading; + +namespace TestableHttpClient.Tests; + + +internal static class NetFrameworkPollyFill +{ + public static Task ReadAsStringAsync(this HttpContent content, CancellationToken cancellationToken = default) + { + return content.ReadAsStringAsync(); + } +} + +#endif diff --git a/test/TestableHttpClient.Tests/Response/JsonResponseTests.cs b/test/TestableHttpClient.Tests/Response/JsonResponseTests.cs index 79b7ac1..ae92024 100644 --- a/test/TestableHttpClient.Tests/Response/JsonResponseTests.cs +++ b/test/TestableHttpClient.Tests/Response/JsonResponseTests.cs @@ -16,7 +16,7 @@ public async Task ExecuteAsync_WithSimpleContent_SetsJsonStringToContent(object? using HttpResponseMessage responseMessage = await sut.TestAsync(); - var json = await responseMessage.Content.ReadAsStringAsync(); + var json = await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken); Assert.Equal(expectedJson, json); Assert.Same(input, sut.Content); @@ -32,9 +32,9 @@ public async Task ExecuteAsync_WithObjectContentAndCustomSettingsFromContext_Set handler.RespondWith(sut); using HttpClient client = new(handler); - using HttpResponseMessage responseMessage = await client.GetAsync("http://example"); + using HttpResponseMessage responseMessage = await client.GetAsync("http://example", TestContext.Current.CancellationToken); - var json = await responseMessage.Content.ReadAsStringAsync(); + var json = await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken); Assert.Equal("{\"Value\":42}", json); Assert.Same(input, sut.Content); @@ -47,7 +47,7 @@ public async Task ExecuteAsync_WithObjectContentAndDefaultSettingsViaContext_Set JsonResponse sut = new(input); using HttpResponseMessage responseMessage = await sut.TestAsync(); - var json = await responseMessage.Content.ReadAsStringAsync(); + var json = await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken); Assert.Equal("{\"value\":42}", json); Assert.Same(input, sut.Content); @@ -64,7 +64,7 @@ public async Task ExecuteAsync_WithObjectContentAndCustomSettingsDirectly_SetsJs using HttpResponseMessage responseMessage = await sut.TestAsync(); - var json = await responseMessage.Content.ReadAsStringAsync(); + var json = await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken); Assert.Equal("{\"Value\":42}", json); Assert.Same(input, sut.Content); @@ -78,7 +78,7 @@ public async Task ExecuteAsync_WithCollectionContent_SetsJsonStringToContent() using HttpResponseMessage responseMessage = await sut.TestAsync(); - var json = await responseMessage.Content.ReadAsStringAsync(); + var json = await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken); Assert.Equal("[1,2,3,4]", json); Assert.Same(input, sut.Content); diff --git a/test/TestableHttpClient.Tests/Response/TextResponseTests.cs b/test/TestableHttpClient.Tests/Response/TextResponseTests.cs index a07306e..57f8e6a 100644 --- a/test/TestableHttpClient.Tests/Response/TextResponseTests.cs +++ b/test/TestableHttpClient.Tests/Response/TextResponseTests.cs @@ -19,7 +19,7 @@ public async Task TextResponse_WithEmptyString_SetsStringToContent() using HttpResponseMessage responseMessage = await sut.TestAsync(); Assert.Equal(string.Empty, sut.Content); - Assert.Equal(string.Empty, await responseMessage.Content.ReadAsStringAsync()); + Assert.Equal(string.Empty, await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); } [Fact] @@ -30,7 +30,7 @@ public async Task TextResponse_WithNotString_SetsStringToContent() using HttpResponseMessage responseMessage = await sut.TestAsync(); Assert.Equal("Hello World", sut.Content); - Assert.Equal("Hello World", await responseMessage.Content.ReadAsStringAsync()); + Assert.Equal("Hello World", await responseMessage.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); } [Fact] diff --git a/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequests.cs b/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequests.cs index 54b3dd3..0ff171a 100644 --- a/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequests.cs +++ b/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequests.cs @@ -42,7 +42,7 @@ public async Task ShouldHaveMadeRequests_WhenRequestsWereMade_ReturnsHttpRequest using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://example.com/")); + _ = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); var result = sut.ShouldHaveMadeRequests(); @@ -57,7 +57,7 @@ public async Task ShouldHaveMadeRequestsWithNumberOfRequests_WhenRequestsWereMad using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://example.com/")); + _ = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); var result = sut.ShouldHaveMadeRequests(1); diff --git a/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequestsTo.cs b/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequestsTo.cs index 9ae1fa9..c826bc7 100644 --- a/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequestsTo.cs +++ b/test/TestableHttpClient.Tests/TestabeHttpMessageHandlerAssertionExtensionsTests/ShouldHaveMadeRequestsTo.cs @@ -72,7 +72,7 @@ public async Task ShouldHaveMadeRequestsTo_WhenMatchingRequestsWithSameCaseWereM using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://example.com/")); + _ = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); var result = sut.ShouldHaveMadeRequestsTo("https://example.com/"); @@ -87,7 +87,7 @@ public async Task ShouldHaveMadeRequestsToWithNumberOfRequests_WhenMatchingReque using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://example.com/")); + _ = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); var result = sut.ShouldHaveMadeRequestsTo("https://example.com/", 1); @@ -102,7 +102,7 @@ public async Task ShouldHaveMadeRequestsTo_WhenMatchingRequestsWithDifferentCase using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://Example.com/Test")); + _ = await client.GetAsync(new Uri("https://Example.com/Test"), TestContext.Current.CancellationToken); var result = sut.ShouldHaveMadeRequestsTo("https://example.com/test"); @@ -118,7 +118,7 @@ public async Task ShouldHaveMadeRequestsTo_WhenMatchingRequestsWithDifferentCase sut.Options.UriPatternMatchingOptions.PathCaseInsensitive = false; using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://Example.com/Test")); + _ = await client.GetAsync(new Uri("https://Example.com/Test"), TestContext.Current.CancellationToken); Assert.Throws(() => sut.ShouldHaveMadeRequestsTo("https://example.com/test")); } @@ -129,7 +129,7 @@ public async Task ShouldHaveMadeRequestsToWithNumberOfRequests_WhenMatchingReque using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://Example.com/Test")); + _ = await client.GetAsync(new Uri("https://Example.com/Test"), TestContext.Current.CancellationToken); var result = sut.ShouldHaveMadeRequestsTo("https://example.com/test", 1); @@ -145,7 +145,7 @@ public async Task ShouldHaveMadeRequestsToWithNumberOfRequests_WhenMatchingReque sut.Options.UriPatternMatchingOptions.PathCaseInsensitive = false; using HttpClient client = new(sut); - _ = await client.GetAsync(new Uri("https://Example.com/Test")); + _ = await client.GetAsync(new Uri("https://Example.com/Test"), TestContext.Current.CancellationToken); Assert.Throws(() => sut.ShouldHaveMadeRequestsTo("https://example.com/test", 1)); } diff --git a/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj b/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj index a808876..c501d52 100644 --- a/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj +++ b/test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj @@ -1,7 +1,8 @@ - net462;net47;net48;net8.0;net9.0 + net472;net48;net8.0;net9.0 + Exe diff --git a/test/TestableHttpClient.Tests/TestableHttpMessageHandlerTests.cs b/test/TestableHttpClient.Tests/TestableHttpMessageHandlerTests.cs index cab049f..feb462d 100644 --- a/test/TestableHttpClient.Tests/TestableHttpMessageHandlerTests.cs +++ b/test/TestableHttpClient.Tests/TestableHttpMessageHandlerTests.cs @@ -14,7 +14,7 @@ public async Task SendAsync_WhenRequestsAreMade_LogsRequests() using HttpClient client = new(sut); using HttpRequestMessage request = new(HttpMethod.Get, "https://example.com/"); - _ = await client.SendAsync(request); + _ = await client.SendAsync(request, TestContext.Current.CancellationToken); Assert.Contains(request, sut.Requests); } @@ -29,10 +29,10 @@ public async Task SendAsync_WhenMultipleRequestsAreMade_AllRequestsAreLogged() using HttpRequestMessage request3 = new(HttpMethod.Delete, "https://example3.com/"); using HttpRequestMessage request4 = new(HttpMethod.Head, "https://example4.com/"); - _ = await client.SendAsync(request1); - _ = await client.SendAsync(request2); - _ = await client.SendAsync(request3); - _ = await client.SendAsync(request4); + _ = await client.SendAsync(request1, TestContext.Current.CancellationToken); + _ = await client.SendAsync(request2, TestContext.Current.CancellationToken); + _ = await client.SendAsync(request3, TestContext.Current.CancellationToken); + _ = await client.SendAsync(request4, TestContext.Current.CancellationToken); Assert.Equal([request1, request2, request3, request4], sut.Requests); } @@ -50,7 +50,7 @@ public async Task SendAsync_ByDefault_CallsExecutAsyncOnIResponse() sut.RespondWith(mockedResponse); using HttpClient client = new(sut); using HttpRequestMessage request = new(HttpMethod.Get, new Uri("https://example.com/")); - using HttpResponseMessage response = await client.SendAsync(request); + using HttpResponseMessage response = await client.SendAsync(request, TestContext.Current.CancellationToken); Assert.NotNull(context); Assert.Same(request, context.HttpRequestMessage); @@ -64,10 +64,10 @@ public async Task SendAsync_ByDefault_ReturnsHttpStatusCodeOK() using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - using HttpResponseMessage result = await client.GetAsync(new Uri("https://example.com/")); + using HttpResponseMessage result = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.OK, result.StatusCode); - Assert.Equal(string.Empty, await result.Content.ReadAsStringAsync()); + Assert.Equal(string.Empty, await result.Content.ReadAsStringAsync(TestContext.Current.CancellationToken)); Assert.NotNull(result.RequestMessage); } @@ -77,8 +77,8 @@ public async Task SendAsync_ByDefault_ReturnsDifferentResponseForEveryRequest() using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - using HttpResponseMessage result1 = await client.GetAsync(new Uri("https://example.com/")); - using HttpResponseMessage result2 = await client.GetAsync(new Uri("https://example.com/")); + using HttpResponseMessage result1 = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); + using HttpResponseMessage result2 = await client.GetAsync(new Uri("https://example.com/"), TestContext.Current.CancellationToken); Assert.NotSame(result1, result2); } @@ -92,8 +92,8 @@ public async Task SendAsync_ByDefault_SetsRequestMessageOnEveryResponse() using HttpRequestMessage request1 = new(HttpMethod.Get, new Uri("https://example.com/1")); using HttpRequestMessage request2 = new(HttpMethod.Post, new Uri("https://example.com/2")); - using HttpResponseMessage response1 = await client.SendAsync(request1); - using HttpResponseMessage response2 = await client.SendAsync(request2); + using HttpResponseMessage response1 = await client.SendAsync(request1, TestContext.Current.CancellationToken); + using HttpResponseMessage response2 = await client.SendAsync(request2, TestContext.Current.CancellationToken); Assert.Same(request1, response1.RequestMessage); Assert.Same(request2, response2.RequestMessage); @@ -116,7 +116,7 @@ public async Task RespondWith_GivenResponse_ReturnsResponse() sut.RespondWith(Responses.StatusCode(HttpStatusCode.NoContent)); using HttpClient client = new(sut); - using HttpResponseMessage response = await client.GetAsync("https://example.com"); + using HttpResponseMessage response = await client.GetAsync("https://example.com", TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); Assert.NotNull(response.RequestMessage); @@ -127,7 +127,7 @@ public async Task ClearRequests_ByDefault_ShouldClearRequests() { using TestableHttpMessageHandler sut = new(); using HttpClient client = new(sut); - _ = await client.GetAsync("https://example.com"); + _ = await client.GetAsync("https://example.com", TestContext.Current.CancellationToken); Assert.NotEmpty(sut.Requests); @@ -138,6 +138,7 @@ public async Task ClearRequests_ByDefault_ShouldClearRequests() [Fact] [SuppressMessage("Usage", "xUnit1031:Do not use blocking task operations in test method", Justification = "Here it is necessary, if it blocks the test, it will time out and breaks the test.")] + [SuppressMessage("Usage", "xUnit1051:Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken", Justification = "We don't want xunit to interfere with this test.")] public void GetAsync_ShouldNotHang() { using TestableHttpMessageHandler sut = new();