Skip to content

Commit 36d77bd

Browse files
authored
Make API more consistent
* Renamed several members on HttpResponseMessageBuilder * Mark HasHttpVersion with string parameter as obsolete. * Do not support null for expectedContent * Add missing HasContent methods on HttpRequestMessageExtensions and HttpResponseMessageExtensions.
1 parent 268dc73 commit 36d77bd

20 files changed

+355
-197
lines changed

src/TestableHttpClient.NFluent/HttpResponseMessageChecks.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,19 +222,17 @@ public static class HttpResponseMessageChecks
222222
/// <param name="check">The fluent check to be extended.</param>
223223
/// <param name="expectedContent">The content that the response should contain, this could be a pattern that includes an astrix ('*').</param>
224224
/// <returns>A check link.</returns>
225-
public static ICheckLink<ICheck<HttpResponseMessage?>> HasContent(this ICheck<HttpResponseMessage?> check, string? expectedContent)
225+
public static ICheckLink<ICheck<HttpResponseMessage?>> HasContent(this ICheck<HttpResponseMessage?> check, string expectedContent)
226226
{
227227
var checkLogic = ExtensibilityHelper.BeginCheck(check)
228228
.SetSutName("response")
229229
.FailIfNull();
230230

231231
if (expectedContent == null)
232232
{
233-
#pragma warning disable CS8602 // Dereference of a possibly null reference. Justification = "Null reference check is performed by the FailIfNull check"
234-
checkLogic.CheckSutAttributes(sut => sut.Content, "content")
235-
#pragma warning restore CS8602 // Dereference of a possibly null reference.
236-
.FailWhen(sut => sut != null, "The {0} should be null.", MessageOption.NoCheckedBlock | MessageOption.NoExpectedBlock)
237-
.OnNegate("The {0} should not be null.", MessageOption.NoCheckedBlock | MessageOption.NoExpectedBlock)
233+
checkLogic
234+
.Fail("The expected content should not be null, but it is.", MessageOption.NoCheckedBlock | MessageOption.NoExpectedBlock)
235+
.CantBeNegated($"{nameof(HasContent)} with {nameof(expectedContent)} set to null")
238236
.EndCheck();
239237
}
240238
else if (expectedContent.Contains("*"))

src/TestableHttpClient.NFluent/TestableHttpClient.NFluent.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
11+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
1212
<PrivateAssets>all</PrivateAssets>
1313
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1414
</PackageReference>

src/TestableHttpClient/HttpRequestMessageAsserter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ public HttpRequestMessageAsserter WithJsonContent(object? jsonObject)
281281
return With(x => x.HasContent(jsonString) && x.HasContentHeader("Content-Type", "application/json*"), $"json content '{jsonString}'");
282282
}
283283

284+
/// <summary>
285+
/// Asserts wheter requests are made with specific url encoded content.
286+
/// </summary>
287+
/// <param name="nameValueCollection">The collection of key/value pairs that should be url encoded.</param>
288+
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
284289
public HttpRequestMessageAsserter WithFormUrlEncodedContent(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
285290
{
286291
if (nameValueCollection == null)

src/TestableHttpClient/HttpRequestMessageExtensions.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,21 @@ public static bool HasMatchingUri(this HttpRequestMessage httpRequestMessage, st
225225
};
226226
}
227227

228+
/// <summary>
229+
/// Determines whether the request has content.
230+
/// </summary>
231+
/// <param name="httpRequestMessage">A <see cref="HttpRequestMessage"/> to check for content.</param>
232+
/// <returns>true when the request has content; otherwise, false.</returns>
233+
public static bool HasContent(this HttpRequestMessage httpRequestMessage)
234+
{
235+
if (httpRequestMessage == null)
236+
{
237+
throw new ArgumentNullException(nameof(httpRequestMessage));
238+
}
239+
240+
return httpRequestMessage.Content != null;
241+
}
242+
228243
/// <summary>
229244
/// Determines whether the request content matches a string pattern.
230245
/// </summary>

src/TestableHttpClient/HttpResponseMessageBuilder.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,18 @@ public sealed class HttpResponseMessageBuilder
2424
/// </summary>
2525
/// <param name="httpVersion">The <see cref="HttpVersion"/> of the response.</param>
2626
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
27+
[Obsolete("Renamed to WithHttpVersion.", true)]
2728
public HttpResponseMessageBuilder WithVersion(Version httpVersion)
29+
{
30+
return WithHttpVersion(httpVersion);
31+
}
32+
33+
/// <summary>
34+
/// Specifies the version of the response.
35+
/// </summary>
36+
/// <param name="httpVersion">The <see cref="HttpVersion"/> of the response.</param>
37+
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
38+
public HttpResponseMessageBuilder WithHttpVersion(Version httpVersion)
2839
{
2940
httpResponseMessage.Version = httpVersion;
3041
return this;
@@ -35,7 +46,18 @@ public HttpResponseMessageBuilder WithVersion(Version httpVersion)
3546
/// </summary>
3647
/// <param name="statusCode">The <see cref="HttpStatusCode"/> of the response.</param>
3748
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
38-
public HttpResponseMessageBuilder WithStatusCode(HttpStatusCode statusCode)
49+
[Obsolete("Renamed to WithHttpStatusCode.", true)]
50+
public HttpResponseMessageBuilder WithStatusCode(HttpStatusCode httpStatusCode)
51+
{
52+
return WithHttpStatusCode(httpStatusCode);
53+
}
54+
55+
/// <summary>
56+
/// Specifies the status code of the response.
57+
/// </summary>
58+
/// <param name="statusCode">The <see cref="HttpStatusCode"/> of the response.</param>
59+
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
60+
public HttpResponseMessageBuilder WithHttpStatusCode(HttpStatusCode statusCode)
3961
{
4062
httpResponseMessage.StatusCode = statusCode;
4163
return this;
@@ -46,7 +68,18 @@ public HttpResponseMessageBuilder WithStatusCode(HttpStatusCode statusCode)
4668
/// </summary>
4769
/// <param name="responseHeaderBuilder">The builder for configuring the response headers.</param>
4870
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
71+
[Obsolete("Renamed to WithResponseHeaders.", true)]
4972
public HttpResponseMessageBuilder WithHeaders(Action<HttpResponseHeaders> responseHeaderBuilder)
73+
{
74+
return WithResponseHeaders(responseHeaderBuilder);
75+
}
76+
77+
/// <summary>
78+
/// Configure request headers using a builder by directly accessing the <see cref="HttpResponseHeaders"/>.
79+
/// </summary>
80+
/// <param name="responseHeaderBuilder">The builder for configuring the response headers.</param>
81+
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
82+
public HttpResponseMessageBuilder WithResponseHeaders(Action<HttpResponseHeaders> responseHeaderBuilder)
5083
{
5184
if (responseHeaderBuilder == null)
5285
{
@@ -63,7 +96,19 @@ public HttpResponseMessageBuilder WithHeaders(Action<HttpResponseHeaders> respon
6396
/// <param name="header">The name of the header to add.</param>
6497
/// <param name="value">The value of the header to add.</param>
6598
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
99+
[Obsolete("Renamed to WithResponseHeader.", true)]
66100
public HttpResponseMessageBuilder WithHeader(string header, string value)
101+
{
102+
return WithResponseHeader(header, value);
103+
}
104+
105+
/// <summary>
106+
/// Adds a request header to the response.
107+
/// </summary>
108+
/// <param name="header">The name of the header to add.</param>
109+
/// <param name="value">The value of the header to add.</param>
110+
/// <returns>The <see cref="HttpResponseMessageBuilder"/> for further building of the response.</returns>
111+
public HttpResponseMessageBuilder WithResponseHeader(string header, string value)
67112
{
68113
if (string.IsNullOrEmpty(header))
69114
{

src/TestableHttpClient/HttpResponseMessageExtensions.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public static bool HasHttpVersion(this HttpResponseMessage httpResponseMessage,
3636
/// <param name="httpResponseMessage">A <see cref="HttpResponseMessage"/> to check the correct version on.</param>
3737
/// <param name="httpVersion">The expected version.</param>
3838
/// <returns>true when the HttpVersion matches; otherwise, false.</returns>
39+
[Obsolete("Use overload with System.Version instead.", true)]
3940
public static bool HasHttpVersion(this HttpResponseMessage httpResponseMessage, string httpVersion)
4041
{
4142
if (httpResponseMessage == null)
@@ -198,6 +199,20 @@ public static bool HasContentHeader(this HttpResponseMessage httpResponseMessage
198199
return httpResponseMessage.Content.Headers.HasHeader(headerName, headerValue);
199200
}
200201

202+
/// <summary>
203+
/// Determines whether the response has content.
204+
/// </summary>
205+
/// <param name="httpResponseMessage">A <see cref="HttpResponseMessage"/> to check for content.</param>
206+
/// <returns>true when the response has content; otherwise, false.</returns>
207+
public static bool HasContent(this HttpResponseMessage httpResponseMessage)
208+
{
209+
if (httpResponseMessage == null)
210+
{
211+
throw new ArgumentNullException(nameof(httpResponseMessage));
212+
}
213+
return httpResponseMessage.Content != null;
214+
}
215+
201216
/// <summary>
202217
/// Determines whether the response content matches a string pattern.
203218
/// </summary>

src/TestableHttpClient/TestableHttpClient.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
11+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
1212
<PrivateAssets>all</PrivateAssets>
1313
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1414
</PackageReference>
15-
<PackageReference Include="System.Text.Json" Version="4.7.1" />
15+
<PackageReference Include="System.Text.Json" Version="4.7.2" />
1616
</ItemGroup>
1717

1818
<Import Project="..\SharedUtilities\SharedUtilities.projitems" Label="Shared" />

test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public async Task UsingTestHandlerWithCustomResponseUsingBuilder_ReturnsCustomRe
4444
using var testHandler = new TestableHttpMessageHandler();
4545
testHandler.RespondWith(response =>
4646
{
47-
response.WithStatusCode(HttpStatusCode.Created)
47+
response.WithHttpStatusCode(HttpStatusCode.Created)
4848
.WithStringContent("HttpClient testing is easy");
4949
});
5050

@@ -59,8 +59,8 @@ public async Task UsingTestHandlerWithCustomResponseUsingBuilder_ReturnsCustomRe
5959
public async Task UsingTestHandlerWithMultipleCustomRepsonse_ReturnsLastCustomResponse()
6060
{
6161
using var testHandler = new TestableHttpMessageHandler();
62-
testHandler.RespondWith(response => response.WithStatusCode(HttpStatusCode.Created).WithStringContent("HttpClient testing is easy"));
63-
testHandler.RespondWith(response => response.WithStatusCode(HttpStatusCode.NotFound).WithJsonContent("Not Found"));
62+
testHandler.RespondWith(response => response.WithHttpStatusCode(HttpStatusCode.Created).WithStringContent("HttpClient testing is easy"));
63+
testHandler.RespondWith(response => response.WithHttpStatusCode(HttpStatusCode.NotFound).WithJsonContent("Not Found"));
6464

6565
using var httpClient = new HttpClient(testHandler);
6666
var result = await httpClient.GetAsync("http://httpbin.org/status/201");
@@ -73,7 +73,7 @@ public async Task UsingTestHandlerWithMultipleCustomRepsonse_ReturnsLastCustomRe
7373
public async Task UsingTestHandlerWithCustomResponse_AlwaysReturnsSameCustomResponse()
7474
{
7575
using var testHandler = new TestableHttpMessageHandler();
76-
testHandler.RespondWith(response => response.WithStatusCode(HttpStatusCode.Created).WithStringContent("HttpClient testing is easy"));
76+
testHandler.RespondWith(response => response.WithHttpStatusCode(HttpStatusCode.Created).WithStringContent("HttpClient testing is easy"));
7777

7878
using var httpClient = new HttpClient(testHandler);
7979
var urls = new[]

test/TestableHttpClient.IntegrationTests/TestableHttpClient.IntegrationTests.csproj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,21 @@
1010

1111
<ItemGroup>
1212
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.4" />
13-
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
13+
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
1414
<PrivateAssets>all</PrivateAssets>
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>
17-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
17+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
1818
<PackageReference Include="Moq" Version="4.14.1" />
1919
<PackageReference Include="xunit" Version="2.4.1" />
20-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
21-
<PackageReference Include="coverlet.collector" Version="1.2.0" />
20+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
21+
<PrivateAssets>all</PrivateAssets>
22+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
23+
</PackageReference>
24+
<PackageReference Include="coverlet.collector" Version="1.2.1">
25+
<PrivateAssets>all</PrivateAssets>
26+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
27+
</PackageReference>
2228
</ItemGroup>
2329

2430
<ItemGroup>

test/TestableHttpClient.IntegrationTests/UsingIHttpClientFactory.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public async Task ConfigureIHttpClientFactoryToUseTestableHttpClient()
1515
{
1616
// Create TestableHttpMessageHandler as usual.
1717
var testableHttpMessageHandler = new TestableHttpMessageHandler();
18-
testableHttpMessageHandler.RespondWith(response => response.WithStatusCode(HttpStatusCode.OK));
18+
testableHttpMessageHandler.RespondWith(response => response.WithHttpStatusCode(HttpStatusCode.OK));
1919

2020
// Create a mock for IHttpClientFactory
2121
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
@@ -34,10 +34,10 @@ public async Task ConfigureIHttpClientFactoryToUseTestableHttpClient()
3434
public async Task ConfigureMultiplehttpClientFactories()
3535
{
3636
var testableGithubHandler = new TestableHttpMessageHandler();
37-
testableGithubHandler.RespondWith(response => response.WithStatusCode(HttpStatusCode.OK).WithHeader("Server", "github"));
37+
testableGithubHandler.RespondWith(response => response.WithHttpStatusCode(HttpStatusCode.OK).WithResponseHeader("Server", "github"));
3838

3939
var testableHttpBinHandler = new TestableHttpMessageHandler();
40-
testableHttpBinHandler.RespondWith(response => response.WithStatusCode(HttpStatusCode.NotFound).WithHeader("Server", "httpbin"));
40+
testableHttpBinHandler.RespondWith(response => response.WithHttpStatusCode(HttpStatusCode.NotFound).WithResponseHeader("Server", "httpbin"));
4141

4242
// Create a mock for IHttpClientFactory
4343
var httpClientFactoryMock = new Mock<IHttpClientFactory>();

0 commit comments

Comments
 (0)