Skip to content

Commit 25b9964

Browse files
authored
Adds content validation methods
Added WithJsonContent asserter. Added WithFormUrlEncoded asserter. Closes #11
1 parent feaccc2 commit 25b9964

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed

src/HttpClientTestHelpers/HttpRequestMessageAsserter.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Net.Http;
5+
using System.Text.Json;
56

67
namespace HttpClientTestHelpers
78
{
@@ -269,6 +270,30 @@ public HttpRequestMessageAsserter WithContent(string pattern)
269270
return With(x => x.HasContent(pattern), $"content '{pattern}'");
270271
}
271272

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+
public HttpRequestMessageAsserter WithFormUrlEncodedContent(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
285+
{
286+
if (nameValueCollection == null)
287+
{
288+
throw new ArgumentNullException(nameof(nameValueCollection));
289+
}
290+
291+
using var content = new FormUrlEncodedContent(nameValueCollection);
292+
var contentString = content.ReadAsStringAsync().Result;
293+
294+
return With(x => x.HasContent(contentString) && x.HasContentHeader("Content-Type", "application/x-www-form-urlencoded*"), $"form url encoded content '{contentString}'");
295+
}
296+
272297
/// <summary>
273298
/// Asserts that a specific amount of requests were made.
274299
/// </summary>

test/HttpClientTestHelpers.IntegrationTests/AssertingRequests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ public async Task AssertingContent()
161161
Assert.Throws<HttpRequestMessageAssertionException>(() => testHandler.ShouldHaveMadeRequests().WithContent("my"));
162162
}
163163

164+
[Fact]
165+
public async Task AssertJsonContent()
166+
{
167+
var testHandler = new TestableHttpMessageHandler();
168+
var client = new HttpClient(testHandler);
169+
170+
_ = await client.PostAsync("https://httpbin.org/post", new StringContent("{}", Encoding.UTF8, "application/json"));
171+
172+
testHandler.ShouldHaveMadeRequests().WithJsonContent(new { });
173+
}
174+
164175
[Fact]
165176
public async Task CustomAssertions()
166177
{

test/HttpClientTestHelpers.Tests/HttpRequestMessageAsserterTests.cs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Net;
45
using System.Net.Http;
6+
using System.Net.Http.Headers;
57
using System.Text;
68

79
using Xunit;
@@ -605,6 +607,107 @@ public void WithContent_RequestWithMatchingContent_ReturnsHttpRequestMessageAsse
605607
Assert.IsType<HttpRequestMessageAsserter>(result);
606608
}
607609

610+
[Fact]
611+
public void WithJsonContent_RequestWithMatchingContent_ReturnsHttpRequestMessageAsserter()
612+
{
613+
var request = new HttpRequestMessage
614+
{
615+
Content = new StringContent("null", Encoding.UTF8, "application/json")
616+
};
617+
var sut = new HttpRequestMessageAsserter(new[] { request });
618+
619+
var result = sut.WithJsonContent(null);
620+
621+
Assert.NotNull(result);
622+
Assert.IsType<HttpRequestMessageAsserter>(result);
623+
}
624+
625+
[Fact]
626+
public void WithJsonContent_RequestWithDifferentContent_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
627+
{
628+
var request = new HttpRequestMessage
629+
{
630+
Content = new StringContent("{}", Encoding.UTF8, "application/json")
631+
};
632+
var sut = new HttpRequestMessageAsserter(new[] { request });
633+
634+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithJsonContent(null));
635+
Assert.Equal("Expected at least one request to be made with json content 'null', but no requests were made.", exception.Message);
636+
}
637+
638+
[Fact]
639+
public void WithJsonContent_RequestWithDifferentContentType_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
640+
{
641+
var request = new HttpRequestMessage
642+
{
643+
Content = new StringContent("null", Encoding.UTF8)
644+
};
645+
var sut = new HttpRequestMessageAsserter(new[] { request });
646+
647+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithJsonContent(null));
648+
Assert.Equal("Expected at least one request to be made with json content 'null', but no requests were made.", exception.Message);
649+
}
650+
651+
#nullable disable
652+
[Fact]
653+
public void WithFormUrlEncodedContent_NullNameValueCollection_ThrowsArgumentNullException()
654+
{
655+
var request = new HttpRequestMessage
656+
{
657+
Content = new FormUrlEncodedContent(Enumerable.Empty<KeyValuePair<string, string>>())
658+
};
659+
var sut = new HttpRequestMessageAsserter(new[] { request });
660+
661+
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithFormUrlEncodedContent(null));
662+
663+
Assert.Equal("nameValueCollection", exception.ParamName);
664+
}
665+
#nullable restore
666+
667+
[Fact]
668+
public void WithFormUrlEncodedContent_RequestWithMatchingContent_ReturnsHttpRequestMessageAsserter()
669+
{
670+
var request = new HttpRequestMessage
671+
{
672+
Content = new FormUrlEncodedContent(Enumerable.Empty<KeyValuePair<string, string>>())
673+
};
674+
var sut = new HttpRequestMessageAsserter(new[] { request });
675+
676+
var result = sut.WithFormUrlEncodedContent(Enumerable.Empty<KeyValuePair<string, string>>());
677+
678+
Assert.NotNull(result);
679+
Assert.IsType<HttpRequestMessageAsserter>(result);
680+
}
681+
682+
[Fact]
683+
public void WithFormUrlEncodedContent_RequestWithNotMatchingContent_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
684+
{
685+
var request = new HttpRequestMessage
686+
{
687+
Content = new FormUrlEncodedContent(Enumerable.Empty<KeyValuePair<string, string>>())
688+
};
689+
var sut = new HttpRequestMessageAsserter(new[] { request });
690+
691+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithFormUrlEncodedContent(new Dictionary<string, string> { ["username"] = "alice" }));
692+
693+
Assert.Equal("Expected at least one request to be made with form url encoded content 'username=alice', but no requests were made.", exception.Message);
694+
}
695+
696+
[Fact]
697+
public void WithFormUrlEncodedContent_RequestWithNotMatchingContentType_ThrowsHttpRequestMessageAssertionExceptionWithSpecificMessage()
698+
{
699+
var request = new HttpRequestMessage
700+
{
701+
Content = new FormUrlEncodedContent(new Dictionary<string, string> { ["username"] = "alice" })
702+
};
703+
request.Content.Headers.ContentType = new MediaTypeHeaderValue("plain/text");
704+
var sut = new HttpRequestMessageAsserter(new[] { request });
705+
706+
var exception = Assert.Throws<HttpRequestMessageAssertionException>(() => sut.WithFormUrlEncodedContent(new Dictionary<string, string> { ["username"] = "alice" }));
707+
708+
Assert.Equal("Expected at least one request to be made with form url encoded content 'username=alice', but no requests were made.", exception.Message);
709+
}
710+
608711
[Fact]
609712
public void Times_ValueLessThan0_ThrowsArgumentException()
610713
{

0 commit comments

Comments
 (0)