From 306c69f4782d3cd5945f83a0e85d1b67efa96a8d Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Mon, 17 Oct 2022 21:50:24 +0200 Subject: [PATCH] Fixes for WireMock.Net.FluentAssertions (callcount behaviour) (#832) * UsingAnyMethod * fix * . --- .../Assertions/WireMockAssertions.cs | 51 ++++++++++--------- .../Settings/WireMockServerSettings.cs | 1 - .../WireMockAssertionsTests.cs | 38 ++++++++++++++ 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/WireMock.Net.FluentAssertions/Assertions/WireMockAssertions.cs b/src/WireMock.Net.FluentAssertions/Assertions/WireMockAssertions.cs index 022917c01..7fb7911f6 100644 --- a/src/WireMock.Net.FluentAssertions/Assertions/WireMockAssertions.cs +++ b/src/WireMock.Net.FluentAssertions/Assertions/WireMockAssertions.cs @@ -12,9 +12,10 @@ namespace WireMock.FluentAssertions; public class WireMockAssertions { + private const string Any = "*"; private readonly int? _callsCount; private IReadOnlyList _requestMessages; - private IReadOnlyList>> _headers; + private readonly IReadOnlyList>> _headers; public WireMockAssertions(IWireMockServer subject, int? callsCount) { @@ -27,12 +28,13 @@ public WireMockAssertions(IWireMockServer subject, int? callsCount) public AndWhichConstraint AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs) { Func predicate = request => string.Equals(request.AbsoluteUrl, absoluteUrl, StringComparison.OrdinalIgnoreCase); + var (filter, condition) = BuildFilterAndCondition(predicate); Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => _requestMessages) - .ForCondition(requests => requests.Any()) + .ForCondition(requests => _callsCount == 0 || requests.Any()) .FailWith( "Expected {context:wiremockserver} to have been called at address matching the absolute url {0}{reason}, but no calls were made.", absoluteUrl @@ -53,15 +55,17 @@ public AndWhichConstraint AtAbsoluteUrl(string absol public AndWhichConstraint AtUrl(string url, string because = "", params object[] becauseArgs) { Func predicate = request => string.Equals(request.Url, url, StringComparison.OrdinalIgnoreCase); + var (filter, condition) = BuildFilterAndCondition(predicate); Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => _requestMessages) - .ForCondition(requests => requests.Any()) + .ForCondition(requests => _callsCount == 0 || requests.Any()) .FailWith( "Expected {context:wiremockserver} to have been called at address matching the url {0}{reason}, but no calls were made.", - url) + url + ) .Then .ForCondition(condition) .FailWith( @@ -79,12 +83,13 @@ public AndWhichConstraint AtUrl(string url, string b public AndWhichConstraint WithProxyUrl(string proxyUrl, string because = "", params object[] becauseArgs) { Func predicate = request => string.Equals(request.ProxyUrl, proxyUrl, StringComparison.OrdinalIgnoreCase); + var (filter, condition) = BuildFilterAndCondition(predicate); Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => _requestMessages) - .ForCondition(requests => requests.Any()) + .ForCondition(requests => _callsCount == 0 || requests.Any()) .FailWith( "Expected {context:wiremockserver} to have been called with proxy url {0}{reason}, but no calls were made.", proxyUrl @@ -94,8 +99,7 @@ public AndWhichConstraint WithProxyUrl(string proxyU .FailWith( "Expected {context:wiremockserver} to have been called with proxy url {0}{reason}, but didn't find it among the calls with {1}.", _ => proxyUrl, - requests => requests - .Select(request => request.ProxyUrl) + requests => requests.Select(request => request.ProxyUrl) ); _requestMessages = filter(_requestMessages).ToList(); @@ -107,23 +111,23 @@ public AndWhichConstraint WithProxyUrl(string proxyU public AndWhichConstraint FromClientIP(string clientIP, string because = "", params object[] becauseArgs) { Func predicate = request => string.Equals(request.ClientIP, clientIP, StringComparison.OrdinalIgnoreCase); + var (filter, condition) = BuildFilterAndCondition(predicate); Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => _requestMessages) - .ForCondition(requests => requests.Any()) + .ForCondition(requests => _callsCount == 0 || requests.Any()) .FailWith( "Expected {context:wiremockserver} to have been called from client IP {0}{reason}, but no calls were made.", - clientIP) - .Then - .ForCondition(requests => - (_callsCount == null && requests.Any(req => req.ClientIP == clientIP)) || - (_callsCount == requests.Count(req => req.ClientIP == clientIP)) + clientIP ) + .Then + .ForCondition(condition) .FailWith( "Expected {context:wiremockserver} to have been called from client IP {0}{reason}, but didn't find it among the calls from IP(s) {1}.", - _ => clientIP, requests => requests.Select(request => request.ClientIP)); + _ => clientIP, requests => requests.Select(request => request.ClientIP) + ); _requestMessages = filter(_requestMessages).ToList(); @@ -199,16 +203,23 @@ public AndConstraint UsingPut(string because = "", params ob public AndConstraint UsingTrace(string because = "", params object[] becauseArgs) => UsingMethod("TRACE", because, becauseArgs); + [CustomAssertion] + public AndConstraint UsingAnyMethod(string because = "", params object[] becauseArgs) + => UsingMethod(Any, because, becauseArgs); + [CustomAssertion] public AndConstraint UsingMethod(string method, string because = "", params object[] becauseArgs) { - Func predicate = request => string.Equals(request.Method, method, StringComparison.OrdinalIgnoreCase); + var any = method == Any; + Func predicate = request => (any && !string.IsNullOrEmpty(request.Method)) || + string.Equals(request.Method, method, StringComparison.OrdinalIgnoreCase); + var (filter, condition) = BuildFilterAndCondition(predicate); Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => _requestMessages) - .ForCondition(requests => requests.Any()) + .ForCondition(requests => _callsCount == 0 || requests.Any()) .FailWith( "Expected {context:wiremockserver} to have been called using method {0}{reason}, but no calls were made.", method @@ -230,12 +241,6 @@ public AndConstraint UsingMethod(string method, string becau { Func, IReadOnlyList> filter = requests => requests.Where(predicate).ToList(); - return - ( - filter, - requests => - (_callsCount == null && filter(_requestMessages).Any()) || - (_callsCount == filter(_requestMessages).Count()) - ); + return (filter, requests => (_callsCount is null && filter(requests).Any()) || _callsCount == filter(requests).Count); } } \ No newline at end of file diff --git a/src/WireMock.Net/Settings/WireMockServerSettings.cs b/src/WireMock.Net/Settings/WireMockServerSettings.cs index ffb241ce8..f8b365851 100644 --- a/src/WireMock.Net/Settings/WireMockServerSettings.cs +++ b/src/WireMock.Net/Settings/WireMockServerSettings.cs @@ -12,7 +12,6 @@ using WireMock.Types; #if USE_ASPNETCORE using Microsoft.Extensions.DependencyInjection; -using WireMock.Types; #endif namespace WireMock.Settings diff --git a/test/WireMock.Net.Tests/FluentAssertions/WireMockAssertionsTests.cs b/test/WireMock.Net.Tests/FluentAssertions/WireMockAssertionsTests.cs index c7b86aa60..90b96855e 100644 --- a/test/WireMock.Net.Tests/FluentAssertions/WireMockAssertionsTests.cs +++ b/test/WireMock.Net.Tests/FluentAssertions/WireMockAssertionsTests.cs @@ -562,6 +562,44 @@ public async Task HaveReceivedACall_UsingTrace_WhenACallWasMadeUsingTrace_Should .UsingTrace(); } + [Fact] + public async Task HaveReceivedACall_UsingAnyMethod_WhenACallWasMadeUsingGet_Should_BeOK() + { + await _httpClient.SendAsync(new HttpRequestMessage(new HttpMethod("GET"), "anyurl")).ConfigureAwait(false); + + _server.Should() + .HaveReceivedACall() + .UsingAnyMethod(); + } + + [Fact] + public void HaveReceivedNoCalls_UsingAnyMethod_WhenNoCallsWereMade_Should_BeOK() + { + _server + .Should() + .HaveReceived(0) + .Calls() + .UsingAnyMethod(); + + _server + .Should() + .HaveReceivedNoCalls() + .UsingAnyMethod(); + } + + [Fact] + public void HaveReceivedNoCalls_AtUrl_WhenNoCallsWereMade_Should_BeOK() + { + _server.Should() + .HaveReceived(0) + .Calls() + .AtUrl(_server.Url ?? string.Empty); + + _server.Should() + .HaveReceivedNoCalls() + .AtUrl(_server.Url ?? string.Empty); + } + public void Dispose() { _server?.Stop();