Skip to content

Commit 7a0a11d

Browse files
authored
Extract check logic to an interface and extension methods.
The interface for asserting a collection of HttpRequestMessages can be shared between the current HttpRequestMessageAsserter and the checks that have to be written for NFluent. Therefore extracting all common logic into extension methods and adding an interface to HttpRequestMessageAsserter will make it easier to implement the NFluent Checks.
1 parent 2dbc7fd commit 7a0a11d

29 files changed

+1665
-1066
lines changed

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Changed
9+
- Introduced `IHttpRequestMessagesCheck` as the public interface for all checks on requests made to `TestableHttpMessageHandler`. It contains the following api:
10+
- `With(Func<HttpRequestMessage, bool>, string)`
11+
- `Times(int)`
12+
- Moved some api's from `TestableHttpMessageHandler` to `TestableHttpMessageHandlerAssertionExtensions`:
13+
- `ShouldHaveMadeRequests(this TestableHttpMessageHandler)`
14+
- `ShouldHaveMadeRequestsTo(this TestableHttpMessageHandler, string)`
15+
- `ShouldNotHaveMadeRequests(this TestableHttpMessageHandler)`
16+
- `ShouldNotHaveMadeRequestsTo(this TestableHttpMessageHandler, string)`
17+
- Moved most methods from `HttpRequestMessageAsserter` to `HttpRequestMessagesCheckExtensions`:
18+
- `WithRequestUri(this IHttpRequestMessagesCheck, string)` which is renamed from `WithUriPattern(this IHttpRequestMessagesCheck, string)`
19+
- `WithHttpMethod(this IHttpRequestMessagesCheck, HttpMethod)`
20+
- `WithHttpVersion(this IHttpRequestMessagesCheck, Version)`
21+
- `WithRequestHeader(this IHttpRequestMessagesCheck, string)`
22+
- `WithRequestHeader(this IHttpRequestMessagesCheck, string, string)`
23+
- `WithContentHeader(this IHttpRequestMessagesCheck, string)`
24+
- `WithContentHeader(this IHttpRequestMessagesCheck, string, string)`
25+
- `WithHeader(this IHttpRequestMessagesCheck, string)`
26+
- `WithHeader(this IHttpRequestMessagesCheck, string, string)`
27+
- `WithContent(this IHttpRequestMessagesCheck, string)`
28+
- `WithJsonContent(this IHttpRequestMessagesCheck, object)`
29+
- `WithFormUrlEncodedContent(this IHttpRequestMessagesCheck, IEnumerable<KeyValuePair<string, string>)`
30+
31+
### Deprecated
32+
- `WithUriPattern(this IHttpRequestMessagesCheck, string)` will be removed in favour of `WithRequestUri(this IHttpRequestMessagesCheck, string)`
33+
34+
### Removed
35+
- `HttpRequestMessageAsserter` is made internal.
836

937
## [0.4] - 2020-05-26
1038
### Removed

TestableHttpClient.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ 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+
CHANGELOG.md = CHANGELOG.md
1718
LICENSE = LICENSE
1819
README.md = README.md
1920
EndProjectSection
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("TestableHttpClient.Tests")]

src/TestableHttpClient/HttpRequestMessageAsserter.cs

Lines changed: 5 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Net.Http;
5-
using System.Text.Json;
65

76
namespace TestableHttpClient
87
{
98
/// <summary>
109
/// This class makes it easy to create assertions on a collection of <seealso cref="HttpRequestMessage"/>s.
1110
/// </summary>
12-
public class HttpRequestMessageAsserter
11+
internal class HttpRequestMessageAsserter : IHttpRequestMessagesCheck
1312
{
1413
private readonly List<string> _expectedConditions = new List<string>();
1514
private readonly bool _negate = false;
@@ -89,8 +88,8 @@ private void Assert(int? count = null)
8988
/// </summary>
9089
/// <param name="requestFilter">The filter to filter requests with before asserting.</param>
9190
/// <param name="condition">The name of the conditon, used in the exception message.</param>
92-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
93-
public HttpRequestMessageAsserter With(Func<HttpRequestMessage, bool> requestFilter, string condition)
91+
/// <returns>The <seealso cref="IHttpRequestMessagesCheck"/> for further assertions.</returns>
92+
public IHttpRequestMessagesCheck With(Func<HttpRequestMessage, bool> requestFilter, string condition)
9493
{
9594
if (!string.IsNullOrEmpty(condition))
9695
{
@@ -102,209 +101,12 @@ public HttpRequestMessageAsserter With(Func<HttpRequestMessage, bool> requestFil
102101
return this;
103102
}
104103

105-
/// <summary>
106-
/// Asserts whether requests were made to a given URI based on a pattern.
107-
/// </summary>
108-
/// <param name="pattern">The uri pattern that is expected.</param>
109-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
110-
public HttpRequestMessageAsserter WithUriPattern(string pattern)
111-
{
112-
if (string.IsNullOrEmpty(pattern))
113-
{
114-
throw new ArgumentNullException(nameof(pattern));
115-
}
116-
117-
var condition = string.Empty;
118-
if (pattern != "*")
119-
{
120-
condition = $"uri pattern '{pattern}'";
121-
}
122-
return With(x => x.HasMatchingUri(pattern), condition);
123-
}
124-
125-
/// <summary>
126-
/// Asserts whether requests were made with a given HTTP Method.
127-
/// </summary>
128-
/// <param name="httpMethod">The <seealso cref="HttpMethod"/> that is expected.</param>
129-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
130-
public HttpRequestMessageAsserter WithHttpMethod(HttpMethod httpMethod)
131-
{
132-
if (httpMethod == null)
133-
{
134-
throw new ArgumentNullException(nameof(httpMethod));
135-
}
136-
137-
return With(x => x.HasHttpMethod(httpMethod), $"HTTP Method '{httpMethod}'");
138-
}
139-
140-
/// <summary>
141-
/// Asserts whether requests were made using a specific HTTP Version.
142-
/// </summary>
143-
/// <param name="httpVersion">The <seealso cref="System.Net.HttpVersion"/> that is expected.</param>
144-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
145-
public HttpRequestMessageAsserter WithHttpVersion(Version httpVersion)
146-
{
147-
if (httpVersion == null)
148-
{
149-
throw new ArgumentNullException(nameof(httpVersion));
150-
}
151-
152-
return With(x => x.HasHttpVersion(httpVersion), $"HTTP Version '{httpVersion}'");
153-
}
154-
155-
/// <summary>
156-
/// Asserts whether requests were made with a specific header name. Values are ignored.
157-
/// </summary>
158-
/// <remarks>This method only asserts headers on <see cref="System.Net.Http.Headers.HttpRequestHeader"/></remarks>
159-
/// <param name="headerName">The name of the header that is expected.</param>
160-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
161-
public HttpRequestMessageAsserter WithRequestHeader(string headerName)
162-
{
163-
if (string.IsNullOrEmpty(headerName))
164-
{
165-
throw new ArgumentNullException(nameof(headerName));
166-
}
167-
return With(x => x.HasRequestHeader(headerName), $"request header '{headerName}'");
168-
}
169-
170-
/// <summary>
171-
/// Asserts whether requests were made with a specific header name and value.
172-
/// </summary>
173-
/// <remarks>This method only asserts headers on <see cref="System.Net.Http.Headers.HttpRequestHeader"/></remarks>
174-
/// <param name="headerName">The name of the header that is expected.</param>
175-
/// <param name="headerValue">The value of the expected header, supports wildcards.</param>
176-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
177-
public HttpRequestMessageAsserter WithRequestHeader(string headerName, string headerValue)
178-
{
179-
if (string.IsNullOrEmpty(headerName))
180-
{
181-
throw new ArgumentNullException(nameof(headerName));
182-
}
183-
if (string.IsNullOrEmpty(headerValue))
184-
{
185-
throw new ArgumentNullException(nameof(headerValue));
186-
}
187-
return With(x => x.HasRequestHeader(headerName, headerValue), $"request header '{headerName}' and value '{headerValue}'");
188-
}
189-
190-
/// <summary>
191-
/// Asserts whether requests were made with a specific header name. Values are ignored.
192-
/// </summary>
193-
/// <remarks>This method only asserts headers on <see cref="System.Net.Http.Headers.HttpContentHeader"/></remarks>
194-
/// <param name="headerName">The name of the header that is expected.</param>
195-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
196-
public HttpRequestMessageAsserter WithContentHeader(string headerName)
197-
{
198-
if (string.IsNullOrEmpty(headerName))
199-
{
200-
throw new ArgumentNullException(nameof(headerName));
201-
}
202-
return With(x => x.HasContentHeader(headerName), $"content header '{headerName}'");
203-
}
204-
205-
/// <summary>
206-
/// Asserts whether requests were made with a specific header name and value.
207-
/// </summary>
208-
/// <remarks>This method only asserts headers on <see cref="System.Net.Http.Headers.HttpContentHeader"/></remarks>
209-
/// <param name="headerName">The name of the header that is expected.</param>
210-
/// <param name="headerValue">The value of the expected header, supports wildcards.</param>
211-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
212-
public HttpRequestMessageAsserter WithContentHeader(string headerName, string headerValue)
213-
{
214-
if (string.IsNullOrEmpty(headerName))
215-
{
216-
throw new ArgumentNullException(nameof(headerName));
217-
}
218-
if (string.IsNullOrEmpty(headerValue))
219-
{
220-
throw new ArgumentNullException(nameof(headerValue));
221-
}
222-
return With(x => x.HasContentHeader(headerName, headerValue), $"content header '{headerName}' and value '{headerValue}'");
223-
}
224-
225-
/// <summary>
226-
/// Asserts whether requests were made with a specific header name. Values are ignored.
227-
/// </summary>
228-
/// <param name="headerName">The name of the header that is expected.</param>
229-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
230-
public HttpRequestMessageAsserter WithHeader(string headerName)
231-
{
232-
if (string.IsNullOrEmpty(headerName))
233-
{
234-
throw new ArgumentNullException(nameof(headerName));
235-
}
236-
return With(x => x.HasRequestHeader(headerName) || x.HasContentHeader(headerName), $"header '{headerName}'");
237-
}
238-
239-
/// <summary>
240-
/// Asserts whether requests were made with a specific header name and value.
241-
/// </summary>
242-
/// <param name="headerName">The name of the header that is expected.</param>
243-
/// <param name="headerValue">The value of the expected header, supports wildcards.</param>
244-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
245-
public HttpRequestMessageAsserter WithHeader(string headerName, string headerValue)
246-
{
247-
if (string.IsNullOrEmpty(headerName))
248-
{
249-
throw new ArgumentNullException(nameof(headerName));
250-
}
251-
if (string.IsNullOrEmpty(headerValue))
252-
{
253-
throw new ArgumentNullException(nameof(headerValue));
254-
}
255-
return With(x => x.HasRequestHeader(headerName, headerValue) || x.HasContentHeader(headerName, headerValue), $"header '{headerName}' and value '{headerValue}'");
256-
}
257-
258-
/// <summary>
259-
/// Asserts whether requests were made with specific content.
260-
/// </summary>
261-
/// <param name="pattern">The expected content, supports wildcards.</param>
262-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
263-
public HttpRequestMessageAsserter WithContent(string pattern)
264-
{
265-
if (pattern == null)
266-
{
267-
throw new ArgumentNullException(nameof(pattern));
268-
}
269-
270-
return With(x => x.HasContent(pattern), $"content '{pattern}'");
271-
}
272-
273-
/// <summary>
274-
/// Asserts wheter requests are made with specific json content.
275-
/// </summary>
276-
/// <param name="jsonObject">The object representation of the expected request content.</param>
277-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
278-
public HttpRequestMessageAsserter WithJsonContent(object? jsonObject)
279-
{
280-
var jsonString = JsonSerializer.Serialize(jsonObject);
281-
return With(x => x.HasContent(jsonString) && x.HasContentHeader("Content-Type", "application/json*"), $"json content '{jsonString}'");
282-
}
283-
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>
289-
public HttpRequestMessageAsserter WithFormUrlEncodedContent(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
290-
{
291-
if (nameValueCollection == null)
292-
{
293-
throw new ArgumentNullException(nameof(nameValueCollection));
294-
}
295-
296-
using var content = new FormUrlEncodedContent(nameValueCollection);
297-
var contentString = content.ReadAsStringAsync().Result;
298-
299-
return With(x => x.HasContent(contentString) && x.HasContentHeader("Content-Type", "application/x-www-form-urlencoded*"), $"form url encoded content '{contentString}'");
300-
}
301-
302104
/// <summary>
303105
/// Asserts that a specific amount of requests were made.
304106
/// </summary>
305107
/// <param name="count">The number of requests that are expected, should be a positive value.</param>
306-
/// <returns>The <seealso cref="HttpRequestMessageAsserter"/> for further assertions.</returns>
307-
public HttpRequestMessageAsserter Times(int count)
108+
/// <returns>The <seealso cref="IHttpRequestMessagesCheck"/> for further assertions.</returns>
109+
public IHttpRequestMessagesCheck Times(int count)
308110
{
309111
if (count < 0)
310112
{

0 commit comments

Comments
 (0)