Skip to content

Commit 712c645

Browse files
committed
Adds support for asserting a specific amount of requests using .Times().
1 parent 7b039e2 commit 712c645

File tree

5 files changed

+83
-5
lines changed

5 files changed

+83
-5
lines changed

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,6 @@ csharp_style_prefer_switch_expression = true:suggestion
8282

8383
dotnet_sort_system_directives_first = true
8484
dotnet_separate_import_directive_groups = true
85+
86+
# CA1303: Do not pass literals as localized parameters
87+
dotnet_diagnostic.CA1303.severity = silent

HttpClientTestHelpers.sln

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ EndProject
1414
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{800147F1-758C-406D-AF75-CB20EB7CDB18}"
1515
ProjectSection(SolutionItems) = preProject
1616
.editorconfig = .editorconfig
17+
LICENSE = LICENSE
18+
README.md = README.md
1719
EndProjectSection
1820
EndProject
1921
Global

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,12 @@ Using HttpClient in code that is unittested is seen as rather difficult, this li
33

44
This library is largly based on the HttpTest functionality from [Flurl](https://flurl.dev), but is focused around the use of HttpClient directly. Since I intend to replace my usage of Flurl.Http with this library, I kept the interface very similar.
55

6+
# Todo before release
7+
The following assertions should be able in the first release:
8+
- WithRequestBody: Compare the body as text
9+
- WithContentType: Or headers in the body of a httprequestmessage
10+
11+
Preferably the follwing setup for responses:
12+
- Simulate timeout
13+
- easier response body creation?
14+

src/HttpClientTestHelpers/HttpRequestMessageAsserter.cs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ private void Assert(int? count = null)
6060
{
6161
var expected = count switch
6262
{
63+
null => "at least one request to be made",
6364
0 => "no requests to be made",
64-
_ => "at least one request to be made",
65+
1 => "one request to be made",
66+
_ => $"{count} requests to be made"
6567
};
6668
var actual = actualCount switch
6769
{
@@ -100,7 +102,7 @@ public HttpRequestMessageAsserter With(Func<HttpRequestMessage, bool> requestFil
100102
}
101103

102104
/// <summary>
103-
/// Asserts wheter requests were made to a given URI based on a pattern.
105+
/// Asserts whether requests were made to a given URI based on a pattern.
104106
/// </summary>
105107
/// <param name="pattern">The uri pattern that is expected.</param>
106108
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
@@ -120,7 +122,7 @@ public HttpRequestMessageAsserter WithUriPattern(string pattern)
120122
}
121123

122124
/// <summary>
123-
/// Asserts wheter requests were made with a given HTTP Method.
125+
/// Asserts whether requests were made with a given HTTP Method.
124126
/// </summary>
125127
/// <param name="httpMethod">The <seealso cref="HttpMethod"/> that is expected.</param>
126128
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
@@ -135,7 +137,7 @@ public HttpRequestMessageAsserter WithHttpMethod(HttpMethod httpMethod)
135137
}
136138

137139
/// <summary>
138-
/// Asserts wheter requests were made using a specific HTTP Version.
140+
/// Asserts whether requests were made using a specific HTTP Version.
139141
/// </summary>
140142
/// <param name="httpVersion">The <seealso cref="System.Net.HttpVersion"/> that is expected.</param>
141143
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
@@ -150,7 +152,7 @@ public HttpRequestMessageAsserter WithHttpVersion(Version httpVersion)
150152
}
151153

152154
/// <summary>
153-
/// Asserts wheter requests were made with a specific header name. Values are ignored.
155+
/// Asserts whether requests were made with a specific header name. Values are ignored.
154156
/// </summary>
155157
/// <param name="headerName">The name of the header that is expected.</param>
156158
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
@@ -163,6 +165,12 @@ public HttpRequestMessageAsserter WithHeader(string headerName)
163165
return With(x => x.HasHeader(headerName), $"header '{headerName}'");
164166
}
165167

168+
/// <summary>
169+
/// Asserts whether requests were made with a specific header name and value.
170+
/// </summary>
171+
/// <param name="headerName">The name of the header that is expected.</param>
172+
/// <param name="headerValue">The value of the expected header, supports wildcards.</param>
173+
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
166174
public HttpRequestMessageAsserter WithHeader(string headerName, string headerValue)
167175
{
168176
if (string.IsNullOrEmpty(headerName))
@@ -175,5 +183,21 @@ public HttpRequestMessageAsserter WithHeader(string headerName, string headerVal
175183
}
176184
return With(x => x.HasHeader(headerName, headerValue), $"header '{headerName}' and value '{headerValue}'");
177185
}
186+
187+
/// <summary>
188+
/// Asserts that a specific amount of requests were made.
189+
/// </summary>
190+
/// <param name="count">The number of requests that are expected, should be a positive value.</param>
191+
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
192+
public HttpRequestMessageAsserter Times(int count)
193+
{
194+
if(count < 0)
195+
{
196+
throw new ArgumentException("Count should not be less than zero", nameof(count));
197+
}
198+
199+
Assert(count);
200+
return this;
201+
}
178202
}
179203
}

test/HttpClientTestHelpers.Tests/HttpRequestMessageAsserterTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,5 +282,45 @@ public void WithHeaderNameAndValue_RequestWithMatchinHeader_ReturnsHttpRequestMe
282282
Assert.NotNull(result);
283283
Assert.IsType<HttpRequestMessageAsserter>(result);
284284
}
285+
286+
[Fact]
287+
public void Times_ValueLessThan0_ThrowsArgumentException()
288+
{
289+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
290+
291+
var exception = Assert.Throws<ArgumentException>(() => sut.Times(-1));
292+
293+
Assert.Equal("count", exception.ParamName);
294+
}
295+
296+
[Fact]
297+
public void Times_NoRequestsAndCount1_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
298+
{
299+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
300+
301+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.Times(1));
302+
303+
Assert.Equal("Expected one request to be made, but no requests were made.", exception.Message);
304+
}
305+
306+
[Fact]
307+
public void Times_NoRequestsAndCount2_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
308+
{
309+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
310+
311+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.Times(2));
312+
313+
Assert.Equal("Expected 2 requests to be made, but no requests were made.", exception.Message);
314+
}
315+
316+
[Fact]
317+
public void Times_NoRequestsAndCount0_ReturnsHttpRequestMessageAsserter()
318+
{
319+
var sut = new HttpRequestMessageAsserter(Enumerable.Empty<HttpRequestMessage>());
320+
321+
var result = sut.Times(0);
322+
Assert.NotNull(result);
323+
Assert.IsType<HttpRequestMessageAsserter>(result);
324+
}
285325
}
286326
}

0 commit comments

Comments
 (0)