Add AtPath and AtAbsolutePath to Assertions projects (#1349)

* Add AtPath and AtAbsolutePath to Assertions projects

* tst
This commit is contained in:
Stef Heyenrath
2025-08-22 19:40:59 +02:00
committed by GitHub
parent ddb181cc52
commit 08117e870b
13 changed files with 278 additions and 12 deletions

View File

@@ -4,11 +4,11 @@ using Stef.Validation;
using WireMock.Server;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
/// <summary>
/// Provides assertion methods to verify the number of calls made to a WireMock server.
/// This class is used in the context of FluentAssertions.
/// This class is used in the context of AwesomeAssertions.
/// </summary>
public class WireMockANumberOfCallsAssertions
{

View File

@@ -0,0 +1,83 @@
// Copyright © WireMock.Net
using WireMock.Extensions;
using WireMock.Matchers;
// ReSharper disable once CheckNamespace
namespace WireMock.AwesomeAssertions;
#pragma warning disable CS1591
public partial class WireMockAssertions
{
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, string> AtAbsolutePath(string absolutePath, string because = "", params object[] becauseArgs)
{
_ = AtAbsolutePath(new ExactMatcher(true, absolutePath), because, becauseArgs);
return new AndWhichConstraint<WireMockAssertions, string>(this, absolutePath);
}
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtAbsolutePath(IStringMatcher absolutePathMatcher, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => absolutePathMatcher.IsPerfectMatch(request.AbsolutePath));
var absolutePath = absolutePathMatcher.GetPatterns().FirstOrDefault().GetPattern();
_chain
.BecauseOf(because, becauseArgs)
.Given(() => RequestMessages)
.ForCondition(requests => CallsCount == 0 || requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the absolute path {0}{reason}, but no calls were made.",
absolutePath
)
.Then
.ForCondition(condition)
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the absolute path {0}{reason}, but didn't find it among the calls to {1}.",
_ => absolutePath,
requests => requests.Select(request => request.AbsolutePath)
);
FilterRequestMessages(filter);
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, absolutePathMatcher);
}
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, string> AtPath(string path, string because = "", params object[] becauseArgs)
{
_ = AtPath(new ExactMatcher(true, path), because, becauseArgs);
return new AndWhichConstraint<WireMockAssertions, string>(this, path);
}
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtPath(IStringMatcher pathMatcher, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => pathMatcher.IsPerfectMatch(request.Path));
var path = pathMatcher.GetPatterns().FirstOrDefault().GetPattern();
_chain
.BecauseOf(because, becauseArgs)
.Given(() => RequestMessages)
.ForCondition(requests => CallsCount == 0 || requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the path {0}{reason}, but no calls were made.",
path
)
.Then
.ForCondition(condition)
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the path {0}{reason}, but didn't find it among the calls to {1}.",
_ => path,
requests => requests.Select(request => request.Path)
);
FilterRequestMessages(filter);
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, pathMatcher);
}
}

View File

@@ -4,7 +4,7 @@ using WireMock.Extensions;
using WireMock.Matchers;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
#pragma warning disable CS1591
public partial class WireMockAssertions

View File

@@ -4,7 +4,7 @@
using System;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
public partial class WireMockAssertions
{

View File

@@ -5,7 +5,7 @@ using System;
using WireMock.Constants;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
public partial class WireMockAssertions
{

View File

@@ -11,7 +11,7 @@ using WireMock.Matchers;
using WireMock.Models;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
public partial class WireMockAssertions
{

View File

@@ -3,7 +3,7 @@
#pragma warning disable CS1591
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
public partial class WireMockAssertions
{

View File

@@ -4,7 +4,7 @@
using System;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
public partial class WireMockAssertions
{

View File

@@ -7,7 +7,7 @@ using WireMock.Matchers;
using WireMock.Server;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
public partial class WireMockAssertions
{

View File

@@ -4,7 +4,7 @@ using AwesomeAssertions.Primitives;
using WireMock.Server;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
namespace WireMock.AwesomeAssertions;
/// <summary>
/// Contains a number of methods to assert that the <see cref="IWireMockServer"/> is in the expected state.

View File

@@ -3,7 +3,7 @@
using WireMock.Server;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions
namespace WireMock.AwesomeAssertions
{
/// <summary>
/// Contains extension methods for custom assertions in unit tests.

View File

@@ -0,0 +1,83 @@
// Copyright © WireMock.Net
using WireMock.Extensions;
using WireMock.Matchers;
// ReSharper disable once CheckNamespace
namespace WireMock.FluentAssertions;
#pragma warning disable CS1591
public partial class WireMockAssertions
{
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, string> AtAbsolutePath(string absolutePath, string because = "", params object[] becauseArgs)
{
_ = AtAbsolutePath(new ExactMatcher(true, absolutePath), because, becauseArgs);
return new AndWhichConstraint<WireMockAssertions, string>(this, absolutePath);
}
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtAbsolutePath(IStringMatcher absolutePathMatcher, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => absolutePathMatcher.IsPerfectMatch(request.AbsolutePath));
var absolutePath = absolutePathMatcher.GetPatterns().FirstOrDefault().GetPattern();
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => RequestMessages)
.ForCondition(requests => CallsCount == 0 || requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the absolute path {0}{reason}, but no calls were made.",
absolutePath
)
.Then
.ForCondition(condition)
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the absolute path {0}{reason}, but didn't find it among the calls to {1}.",
_ => absolutePath,
requests => requests.Select(request => request.AbsolutePath)
);
FilterRequestMessages(filter);
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, absolutePathMatcher);
}
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, string> AtPath(string path, string because = "", params object[] becauseArgs)
{
_ = AtPath(new ExactMatcher(true, path), because, becauseArgs);
return new AndWhichConstraint<WireMockAssertions, string>(this, path);
}
[CustomAssertion]
public AndWhichConstraint<WireMockAssertions, IStringMatcher> AtPath(IStringMatcher pathMatcher, string because = "", params object[] becauseArgs)
{
var (filter, condition) = BuildFilterAndCondition(request => pathMatcher.IsPerfectMatch(request.Path));
var path = pathMatcher.GetPatterns().FirstOrDefault().GetPattern();
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => RequestMessages)
.ForCondition(requests => CallsCount == 0 || requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the path {0}{reason}, but no calls were made.",
path
)
.Then
.ForCondition(condition)
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the path {0}{reason}, but didn't find it among the calls to {1}.",
_ => path,
requests => requests.Select(request => request.Path)
);
FilterRequestMessages(filter);
return new AndWhichConstraint<WireMockAssertions, IStringMatcher>(this, pathMatcher);
}
}

View File

@@ -108,7 +108,7 @@ public class WireMockAssertionsTests : IDisposable
}
[Fact]
public async Task HaveReceivedACall_AtAbsoluteUrlWilcardMAtcher_WhenACallWasMadeToAbsoluteUrl_Should_BeOK()
public async Task HaveReceivedACall_AtAbsoluteUrlWildcardMatcher_WhenACallWasMadeToAbsoluteUrl_Should_BeOK()
{
await _httpClient.GetAsync("anyurl").ConfigureAwait(false);
@@ -143,6 +143,106 @@ public class WireMockAssertionsTests : IDisposable
.WithMessage($"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 HaveReceivedNoCalls_AtAbsolutePath_WhenACallWasNotMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.GetAsync("xxx").ConfigureAwait(false);
_server.Should()
.HaveReceivedNoCalls()
.AtAbsolutePath("anypath");
}
[Fact]
public async Task HaveReceived0Calls_AtAbsolutePath_WhenACallWasNotMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.GetAsync("xxx").ConfigureAwait(false);
_server.Should()
.HaveReceived(0).Calls()
.AtAbsolutePath("anypath");
}
[Fact]
public async Task HaveReceived1Calls_AtAbsolutePath_WhenACallWasMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.GetAsync("anypath").ConfigureAwait(false);
_server.Should()
.HaveReceived(1).Calls()
.AtAbsolutePath("/anypath");
}
[Fact]
public async Task HaveReceived1Calls_AtAbsolutePathUsingPost_WhenAPostCallWasMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.PostAsync("anypath", new StringContent("")).ConfigureAwait(false);
_server.Should()
.HaveReceived(1).Calls()
.AtAbsolutePath("/anypath")
.And
.UsingPost();
}
[Fact]
public async Task HaveReceived2Calls_AtAbsolutePath_WhenACallWasMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.GetAsync("anypath").ConfigureAwait(false);
await _httpClient.GetAsync("anypath").ConfigureAwait(false);
_server.Should()
.HaveReceived(2).Calls()
.AtAbsolutePath("/anypath");
}
[Fact]
public async Task HaveReceivedACall_AtAbsolutePath_WhenACallWasMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.GetAsync("anypath").ConfigureAwait(false);
_server.Should()
.HaveReceivedACall()
.AtAbsolutePath(new WildcardMatcher("/any*"));
}
[Fact]
public async Task HaveReceivedACall_AtAbsolutePathWildcardMatcher_WhenACallWasMadeToAbsolutePath_Should_BeOK()
{
await _httpClient.GetAsync("anypath").ConfigureAwait(false);
_server.Should()
.HaveReceivedACall()
.AtAbsolutePath("/anypath");
}
[Fact]
public void HaveReceivedACall_AtAbsolutePath_Should_ThrowWhenNoCallsWereMade()
{
Action act = () => _server.Should()
.HaveReceivedACall()
.AtAbsolutePath("anypath");
act.Should()
.Throw<Exception>()
.WithMessage("Expected _server to have been called at address matching the absolute path \"anypath\", but no calls were made.");
}
[Fact]
public async Task HaveReceivedACall_AtAbsolutePath_Should_ThrowWhenNoCallsMatchingTheAbsolutePathWereMade()
{
await _httpClient.GetAsync("").ConfigureAwait(false);
Action act = () => _server.Should()
.HaveReceivedACall()
.AtAbsolutePath("/anypath");
act.Should()
.Throw<Exception>()
.WithMessage($"Expected _server to have been called at address matching the absolute path \"/anypath\", but didn't find it among the calls to {{\"/\"}}.");
}
[Fact]
public async Task HaveReceivedACall_WithHeader_WhenACallWasMadeWithExpectedHeader_Should_BeOK()
{