mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-21 00:28:59 +01:00
Add fluent assertions for headers (#485)
* Add headers assertions * Update FluentAssertions tests with suggested changes
This commit is contained in:
@@ -8,19 +8,20 @@ namespace WireMock.FluentAssertions
|
||||
{
|
||||
public class WireMockAssertions
|
||||
{
|
||||
private readonly IWireMockServer _instance;
|
||||
private readonly IWireMockServer _subject;
|
||||
|
||||
public WireMockAssertions(IWireMockServer instance, int? callsCount)
|
||||
public WireMockAssertions(IWireMockServer subject, int? callsCount)
|
||||
{
|
||||
_instance = instance;
|
||||
_subject = subject;
|
||||
}
|
||||
|
||||
[CustomAssertion]
|
||||
public AndConstraint<WireMockAssertions> AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs)
|
||||
public AndConstraint<WireMockAssertions> AtAbsoluteUrl(string absoluteUrl, string because = "",
|
||||
params object[] becauseArgs)
|
||||
{
|
||||
Execute.Assertion
|
||||
.BecauseOf(because, becauseArgs)
|
||||
.Given(() => _instance.LogEntries.Select(x => x.RequestMessage).ToList())
|
||||
.Given(() => _subject.LogEntries.Select(x => x.RequestMessage).ToList())
|
||||
.ForCondition(requests => requests.Any())
|
||||
.FailWith(
|
||||
"Expected {context:wiremockserver} to have been called at address matching the absolute url {0}{reason}, but no calls were made.",
|
||||
@@ -33,5 +34,43 @@ namespace WireMock.FluentAssertions
|
||||
|
||||
return new AndConstraint<WireMockAssertions>(this);
|
||||
}
|
||||
|
||||
[CustomAssertion]
|
||||
public AndConstraint<WireMockAssertions> WithHeader(string expectedKey, string value,
|
||||
string because = "", params object[] becauseArgs)
|
||||
=> WithHeader(expectedKey, new[] {value}, because, becauseArgs);
|
||||
|
||||
[CustomAssertion]
|
||||
public AndConstraint<WireMockAssertions> WithHeader(string expectedKey, string[] expectedValues,
|
||||
string because = "", params object[] becauseArgs)
|
||||
{
|
||||
var headersDictionary = _subject.LogEntries.SelectMany(x => x.RequestMessage.Headers)
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
using (new AssertionScope("headers from requests sent"))
|
||||
{
|
||||
headersDictionary.Should().ContainKey(expectedKey, because, becauseArgs);
|
||||
}
|
||||
|
||||
using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)"))
|
||||
{
|
||||
if (expectedValues.Length == 1)
|
||||
{
|
||||
headersDictionary[expectedKey].Should().Contain(expectedValues.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
var trimmedHeaderValues = string.Join(",", headersDictionary[expectedKey].Select(x => x)).Split(',')
|
||||
.Select(x => x.Trim())
|
||||
.ToList();
|
||||
foreach (var expectedValue in expectedValues)
|
||||
{
|
||||
trimmedHeaderValues.Should().Contain(expectedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AndConstraint<WireMockAssertions>(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using Xunit;
|
||||
using WireMock.FluentAssertions;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Environment;
|
||||
|
||||
namespace WireMock.Net.Tests.FluentAssertions
|
||||
{
|
||||
@@ -14,15 +17,26 @@ namespace WireMock.Net.Tests.FluentAssertions
|
||||
{
|
||||
private WireMockServer _server;
|
||||
private HttpClient _httpClient;
|
||||
private const int Port = 42000;
|
||||
private int _portUsed;
|
||||
|
||||
public WireMockAssertionsTests()
|
||||
{
|
||||
_server = WireMockServer.Start(Port);
|
||||
_server = WireMockServer.Start();
|
||||
_server.Given(Request.Create().UsingAnyMethod())
|
||||
.RespondWith(Response.Create().WithStatusCode(200));
|
||||
.RespondWith(Response.Create().WithStatusCode(200));
|
||||
_portUsed = _server.Ports.First();
|
||||
|
||||
_httpClient = new HttpClient { BaseAddress = new Uri($"http://localhost:{Port}") };
|
||||
_httpClient = new HttpClient { BaseAddress = new Uri($"http://localhost:{_portUsed}") };
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AtAbsoluteUrl_WhenACallWasMadeToAbsoluteUrl_Should_BeOK()
|
||||
{
|
||||
await _httpClient.GetAsync("anyurl");
|
||||
|
||||
_server.Should()
|
||||
.HaveReceivedACall()
|
||||
.AtAbsoluteUrl($"http://localhost:{_portUsed}/anyurl");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -50,7 +64,96 @@ namespace WireMock.Net.Tests.FluentAssertions
|
||||
act.Should().Throw<Exception>()
|
||||
.And.Message.Should()
|
||||
.Be(
|
||||
$"Expected _server to have been called at address matching the absolute url \"anyurl\", but didn't find it among the calls to {{\"http://localhost:{Port}/\"}}.");
|
||||
$"Expected _server to have been called at address matching the absolute url \"anyurl\", but didn't find it among the calls to {{\"http://localhost:{_portUsed}/\"}}.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithHeader_WhenACallWasMadeWithExpectedHeader_Should_BeOK()
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer a");
|
||||
await _httpClient.GetAsync("");
|
||||
|
||||
_server.Should()
|
||||
.HaveReceivedACall()
|
||||
.WithHeader("Authorization", "Bearer a");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithHeader_WhenACallWasMadeWithExpectedHeaderAmongMultipleHeaderValues_Should_BeOK()
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
await _httpClient.GetAsync("");
|
||||
|
||||
_server.Should()
|
||||
.HaveReceivedACall()
|
||||
.WithHeader("Accept", new[] { "application/xml", "application/json" });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithHeader_Should_ThrowWhenNoCallsMatchingTheHeaderNameWereMade()
|
||||
{
|
||||
await _httpClient.GetAsync("");
|
||||
|
||||
Action act = () => _server.Should()
|
||||
.HaveReceivedACall()
|
||||
.WithHeader("Authorization", "value");
|
||||
|
||||
var sentHeaders = _server.LogEntries.SelectMany(x => x.RequestMessage.Headers)
|
||||
.ToDictionary(x => x.Key, x => x.Value)
|
||||
.ToList();
|
||||
|
||||
var sentHeaderString = "{" + string.Join(", ", sentHeaders) + "}";
|
||||
|
||||
act.Should().Throw<Exception>()
|
||||
.And.Message.Should()
|
||||
.Be(
|
||||
$"Expected headers from requests sent {sentHeaderString} to contain key \"Authorization\".{NewLine}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithHeader_Should_ThrowWhenNoCallsMatchingTheHeaderValuesWereMade()
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
await _httpClient.GetAsync("");
|
||||
|
||||
Action act = () => _server.Should()
|
||||
.HaveReceivedACall()
|
||||
.WithHeader("Accept", "missing-value");
|
||||
|
||||
var sentHeaders = _server.LogEntries.SelectMany(x => x.RequestMessage.Headers)
|
||||
.ToDictionary(x => x.Key, x => x.Value)["Accept"]
|
||||
.Select(x => $"\"{x}\"")
|
||||
.ToList();
|
||||
|
||||
var sentHeaderString = "{" + string.Join(", ", sentHeaders) + "}";
|
||||
|
||||
act.Should().Throw<Exception>()
|
||||
.And.Message.Should()
|
||||
.Be(
|
||||
$"Expected header \"Accept\" from requests sent with value(s) {sentHeaderString} to contain \"missing-value\".{NewLine}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithHeader_Should_ThrowWhenNoCallsMatchingTheHeaderWithMultipleValuesWereMade()
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
|
||||
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
await _httpClient.GetAsync("");
|
||||
|
||||
Action act = () => _server.Should()
|
||||
.HaveReceivedACall()
|
||||
.WithHeader("Accept", new[] { "missing-value1", "missing-value2" });
|
||||
|
||||
const string missingValue1Message =
|
||||
"Expected header \"Accept\" from requests sent with value(s) {\"application/xml\", \"application/json\"} to contain \"missing-value1\".";
|
||||
const string missingValue2Message =
|
||||
"Expected header \"Accept\" from requests sent with value(s) {\"application/xml\", \"application/json\"} to contain \"missing-value2\".";
|
||||
|
||||
act.Should().Throw<Exception>()
|
||||
.And.Message.Should()
|
||||
.Be($"{string.Join(NewLine, missingValue1Message, missingValue2Message)}{NewLine}");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -59,4 +162,4 @@ namespace WireMock.Net.Tests.FluentAssertions
|
||||
_server?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user