mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-30 06:12:18 +02:00
FluentAssertions - WithBody and WithBodyAsJson and WithBodyAsBytes (#1014)
* WithBody * . * fix * . * .
This commit is contained in:
@@ -94,23 +94,23 @@ public interface IRequestMessage
|
|||||||
IBodyData? BodyData { get; }
|
IBodyData? BodyData { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The original body as string. Convenience getter for Handlebars.
|
/// The original body as string. Convenience getter for Handlebars and WireMockAssertions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string? Body { get; }
|
string? Body { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The body (as JSON object). Convenience getter for Handlebars.
|
/// The body (as JSON object). Convenience getter for Handlebars and WireMockAssertions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
object? BodyAsJson { get; }
|
object? BodyAsJson { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The body (as bytearray). Convenience getter for Handlebars.
|
/// The body (as bytearray). Convenience getter for Handlebars and WireMockAssertions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
byte[]? BodyAsBytes { get; }
|
byte[]? BodyAsBytes { get; }
|
||||||
|
|
||||||
#if MIMEKIT
|
#if MIMEKIT
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The original body as MimeMessage. Convenience getter for Handlebars.
|
/// The original body as MimeMessage. Convenience getter for Handlebars and WireMockAssertions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
object? BodyAsMimeMessage { get; }
|
object? BodyAsMimeMessage { get; }
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Stef.Validation;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
@@ -10,7 +11,7 @@ namespace WireMock.FluentAssertions
|
|||||||
|
|
||||||
public WireMockANumberOfCallsAssertions(IWireMockServer server, int callsCount)
|
public WireMockANumberOfCallsAssertions(IWireMockServer server, int callsCount)
|
||||||
{
|
{
|
||||||
_server = server;
|
_server = Guard.NotNull(server);
|
||||||
_callsCount = callsCount;
|
_callsCount = callsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#pragma warning disable CS1591
|
||||||
|
using System;
|
||||||
|
using WireMock.Constants;
|
||||||
|
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
namespace WireMock.FluentAssertions;
|
||||||
|
|
||||||
|
public partial class WireMockAssertions
|
||||||
|
{
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingConnect(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.CONNECT, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingDelete(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.DELETE, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingGet(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.GET, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingHead(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.HEAD, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingOptions(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.OPTIONS, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingPost(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.POST, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingPatch(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.PATCH, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingPut(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.PUT, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingTrace(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(HttpRequestMethod.TRACE, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingAnyMethod(string because = "", params object[] becauseArgs)
|
||||||
|
=> UsingMethod(Any, because, becauseArgs);
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> UsingMethod(string method, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
var any = method == Any;
|
||||||
|
Func<IRequestMessage, bool> 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 => _callsCount == 0 || requests.Any())
|
||||||
|
.FailWith(
|
||||||
|
"Expected {context:wiremockserver} to have been called using method {0}{reason}, but no calls were made.",
|
||||||
|
method
|
||||||
|
)
|
||||||
|
.Then
|
||||||
|
.ForCondition(condition)
|
||||||
|
.FailWith(
|
||||||
|
"Expected {context:wiremockserver} to have been called using method {0}{reason}, but didn't find it among the methods {1}.",
|
||||||
|
_ => method,
|
||||||
|
requests => requests.Select(request => request.Method)
|
||||||
|
);
|
||||||
|
|
||||||
|
_requestMessages = filter(_requestMessages).ToList();
|
||||||
|
|
||||||
|
return new AndConstraint<WireMockAssertions>(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
#pragma warning disable CS1591
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using WireMock.Matchers;
|
||||||
|
|
||||||
|
// ReSharper disable once CheckNamespace
|
||||||
|
namespace WireMock.FluentAssertions;
|
||||||
|
|
||||||
|
public partial class WireMockAssertions
|
||||||
|
{
|
||||||
|
private const string MessageFormatNoCalls = "Expected {context:wiremockserver} to have been called using body {0}{reason}, but no calls were made.";
|
||||||
|
private const string MessageFormat = "Expected {context:wiremockserver} to have been called using body {0}{reason}, but didn't find it among the body {1}.";
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBody(string body, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
return WithBody(new WildcardMatcher(body), because, becauseArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBodyAsJson(object body, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
return WithBodyAsJson(new JsonMatcher(body), because, becauseArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBodyAsJson(string body, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
return WithBodyAsJson(new JsonMatcher(body), because, becauseArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBodyAsBytes(byte[] body, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
return WithBodyAsBytes(new ExactObjectMatcher(body), because, becauseArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBody(IStringMatcher matcher, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
var (filter, condition) = BuildFilterAndCondition(r => r.Body, matcher);
|
||||||
|
|
||||||
|
return ExecuteAssertionWithBodyStringMatcher(matcher, because, becauseArgs, condition, filter, r => r.Body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBodyAsJson(IValueMatcher matcher, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
var (filter, condition) = BuildFilterAndCondition(r => r.BodyAsJson, matcher);
|
||||||
|
|
||||||
|
return ExecuteAssertionWithBodyAsJsonValueMatcher(matcher, because, becauseArgs, condition, filter, r => r.BodyAsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CustomAssertion]
|
||||||
|
public AndConstraint<WireMockAssertions> WithBodyAsBytes(ExactObjectMatcher matcher, string because = "", params object[] becauseArgs)
|
||||||
|
{
|
||||||
|
var (filter, condition) = BuildFilterAndCondition(r => r.BodyAsBytes, matcher);
|
||||||
|
|
||||||
|
return ExecuteAssertionWithBodyAsBytesExactObjectMatcher(matcher, because, becauseArgs, condition, filter, r => r.BodyAsBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AndConstraint<WireMockAssertions> ExecuteAssertionWithBodyStringMatcher(
|
||||||
|
IStringMatcher matcher,
|
||||||
|
string because,
|
||||||
|
object[] becauseArgs,
|
||||||
|
Func<IReadOnlyList<IRequestMessage>, bool> condition,
|
||||||
|
Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> filter,
|
||||||
|
Func<IRequestMessage, object?> expression
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Execute.Assertion
|
||||||
|
.BecauseOf(because, becauseArgs)
|
||||||
|
.Given(() => _requestMessages)
|
||||||
|
.ForCondition(requests => _callsCount == 0 || requests.Any())
|
||||||
|
.FailWith(
|
||||||
|
MessageFormatNoCalls,
|
||||||
|
matcher.GetPatterns()
|
||||||
|
)
|
||||||
|
.Then
|
||||||
|
.ForCondition(condition)
|
||||||
|
.FailWith(
|
||||||
|
MessageFormat,
|
||||||
|
_ => matcher.GetPatterns(),
|
||||||
|
requests => requests.Select(expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
_requestMessages = filter(_requestMessages).ToList();
|
||||||
|
|
||||||
|
return new AndConstraint<WireMockAssertions>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AndConstraint<WireMockAssertions> ExecuteAssertionWithBodyAsJsonValueMatcher(
|
||||||
|
IValueMatcher matcher,
|
||||||
|
string because,
|
||||||
|
object[] becauseArgs,
|
||||||
|
Func<IReadOnlyList<IRequestMessage>, bool> condition,
|
||||||
|
Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> filter,
|
||||||
|
Func<IRequestMessage, object?> expression
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Execute.Assertion
|
||||||
|
.BecauseOf(because, becauseArgs)
|
||||||
|
.Given(() => _requestMessages)
|
||||||
|
.ForCondition(requests => _callsCount == 0 || requests.Any())
|
||||||
|
.FailWith(
|
||||||
|
MessageFormatNoCalls,
|
||||||
|
matcher.Value
|
||||||
|
)
|
||||||
|
.Then
|
||||||
|
.ForCondition(condition)
|
||||||
|
.FailWith(
|
||||||
|
MessageFormat,
|
||||||
|
_ => matcher.Value,
|
||||||
|
requests => requests.Select(expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
_requestMessages = filter(_requestMessages).ToList();
|
||||||
|
|
||||||
|
return new AndConstraint<WireMockAssertions>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AndConstraint<WireMockAssertions> ExecuteAssertionWithBodyAsBytesExactObjectMatcher(
|
||||||
|
ExactObjectMatcher matcher,
|
||||||
|
string because,
|
||||||
|
object[] becauseArgs,
|
||||||
|
Func<IReadOnlyList<IRequestMessage>, bool> condition,
|
||||||
|
Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> filter,
|
||||||
|
Func<IRequestMessage, object?> expression
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Execute.Assertion
|
||||||
|
.BecauseOf(because, becauseArgs)
|
||||||
|
.Given(() => _requestMessages)
|
||||||
|
.ForCondition(requests => _callsCount == 0 || requests.Any())
|
||||||
|
.FailWith(
|
||||||
|
MessageFormatNoCalls,
|
||||||
|
matcher.ValueAsObject ?? matcher.ValueAsBytes
|
||||||
|
)
|
||||||
|
.Then
|
||||||
|
.ForCondition(condition)
|
||||||
|
.FailWith(
|
||||||
|
MessageFormat,
|
||||||
|
_ => matcher.ValueAsObject ?? matcher.ValueAsBytes,
|
||||||
|
requests => requests.Select(expression)
|
||||||
|
);
|
||||||
|
|
||||||
|
_requestMessages = filter(_requestMessages).ToList();
|
||||||
|
|
||||||
|
return new AndConstraint<WireMockAssertions>(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using WireMock.Matchers;
|
||||||
using FluentAssertions;
|
|
||||||
using FluentAssertions.Execution;
|
|
||||||
using WireMock.Constants;
|
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
namespace WireMock.FluentAssertions;
|
namespace WireMock.FluentAssertions;
|
||||||
|
|
||||||
public class WireMockAssertions
|
public partial class WireMockAssertions
|
||||||
{
|
{
|
||||||
private const string Any = "*";
|
private const string Any = "*";
|
||||||
private readonly int? _callsCount;
|
private readonly int? _callsCount;
|
||||||
@@ -28,9 +25,7 @@ public class WireMockAssertions
|
|||||||
[CustomAssertion]
|
[CustomAssertion]
|
||||||
public AndWhichConstraint<WireMockAssertions, string> AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs)
|
public AndWhichConstraint<WireMockAssertions, string> AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs)
|
||||||
{
|
{
|
||||||
Func<IRequestMessage, bool> predicate = request => string.Equals(request.AbsoluteUrl, absoluteUrl, StringComparison.OrdinalIgnoreCase);
|
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.AbsoluteUrl, absoluteUrl, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var (filter, condition) = BuildFilterAndCondition(predicate);
|
|
||||||
|
|
||||||
Execute.Assertion
|
Execute.Assertion
|
||||||
.BecauseOf(because, becauseArgs)
|
.BecauseOf(because, becauseArgs)
|
||||||
@@ -55,9 +50,7 @@ public class WireMockAssertions
|
|||||||
[CustomAssertion]
|
[CustomAssertion]
|
||||||
public AndWhichConstraint<WireMockAssertions, string> AtUrl(string url, string because = "", params object[] becauseArgs)
|
public AndWhichConstraint<WireMockAssertions, string> AtUrl(string url, string because = "", params object[] becauseArgs)
|
||||||
{
|
{
|
||||||
Func<IRequestMessage, bool> predicate = request => string.Equals(request.Url, url, StringComparison.OrdinalIgnoreCase);
|
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.Url, url, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var (filter, condition) = BuildFilterAndCondition(predicate);
|
|
||||||
|
|
||||||
Execute.Assertion
|
Execute.Assertion
|
||||||
.BecauseOf(because, becauseArgs)
|
.BecauseOf(because, becauseArgs)
|
||||||
@@ -83,9 +76,7 @@ public class WireMockAssertions
|
|||||||
[CustomAssertion]
|
[CustomAssertion]
|
||||||
public AndWhichConstraint<WireMockAssertions, string> WithProxyUrl(string proxyUrl, string because = "", params object[] becauseArgs)
|
public AndWhichConstraint<WireMockAssertions, string> WithProxyUrl(string proxyUrl, string because = "", params object[] becauseArgs)
|
||||||
{
|
{
|
||||||
Func<IRequestMessage, bool> predicate = request => string.Equals(request.ProxyUrl, proxyUrl, StringComparison.OrdinalIgnoreCase);
|
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.ProxyUrl, proxyUrl, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var (filter, condition) = BuildFilterAndCondition(predicate);
|
|
||||||
|
|
||||||
Execute.Assertion
|
Execute.Assertion
|
||||||
.BecauseOf(because, becauseArgs)
|
.BecauseOf(because, becauseArgs)
|
||||||
@@ -111,9 +102,7 @@ public class WireMockAssertions
|
|||||||
[CustomAssertion]
|
[CustomAssertion]
|
||||||
public AndWhichConstraint<WireMockAssertions, string> FromClientIP(string clientIP, string because = "", params object[] becauseArgs)
|
public AndWhichConstraint<WireMockAssertions, string> FromClientIP(string clientIP, string because = "", params object[] becauseArgs)
|
||||||
{
|
{
|
||||||
Func<IRequestMessage, bool> predicate = request => string.Equals(request.ClientIP, clientIP, StringComparison.OrdinalIgnoreCase);
|
var (filter, condition) = BuildFilterAndCondition(request => string.Equals(request.ClientIP, clientIP, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
var (filter, condition) = BuildFilterAndCondition(predicate);
|
|
||||||
|
|
||||||
Execute.Assertion
|
Execute.Assertion
|
||||||
.BecauseOf(because, becauseArgs)
|
.BecauseOf(because, becauseArgs)
|
||||||
@@ -168,80 +157,20 @@ public class WireMockAssertions
|
|||||||
return new AndConstraint<WireMockAssertions>(this);
|
return new AndConstraint<WireMockAssertions>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingConnect(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.CONNECT, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingDelete(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.DELETE, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingGet(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.GET, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingHead(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.HEAD, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingOptions(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.OPTIONS, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingPost(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.POST, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingPatch(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.PATCH, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingPut(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.PUT, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingTrace(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(HttpRequestMethod.TRACE, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingAnyMethod(string because = "", params object[] becauseArgs)
|
|
||||||
=> UsingMethod(Any, because, becauseArgs);
|
|
||||||
|
|
||||||
[CustomAssertion]
|
|
||||||
public AndConstraint<WireMockAssertions> UsingMethod(string method, string because = "", params object[] becauseArgs)
|
|
||||||
{
|
|
||||||
var any = method == Any;
|
|
||||||
Func<IRequestMessage, bool> 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 => _callsCount == 0 || requests.Any())
|
|
||||||
.FailWith(
|
|
||||||
"Expected {context:wiremockserver} to have been called using method {0}{reason}, but no calls were made.",
|
|
||||||
method
|
|
||||||
)
|
|
||||||
.Then
|
|
||||||
.ForCondition(condition)
|
|
||||||
.FailWith(
|
|
||||||
"Expected {context:wiremockserver} to have been called using method {0}{reason}, but didn't find it among the methods {1}.",
|
|
||||||
_ => method,
|
|
||||||
requests => requests.Select(request => request.Method)
|
|
||||||
);
|
|
||||||
|
|
||||||
_requestMessages = filter(_requestMessages).ToList();
|
|
||||||
|
|
||||||
return new AndConstraint<WireMockAssertions>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private (Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> Filter, Func<IReadOnlyList<IRequestMessage>, bool> Condition) BuildFilterAndCondition(Func<IRequestMessage, bool> predicate)
|
private (Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> Filter, Func<IReadOnlyList<IRequestMessage>, bool> Condition) BuildFilterAndCondition(Func<IRequestMessage, bool> predicate)
|
||||||
{
|
{
|
||||||
Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> filter = requests => requests.Where(predicate).ToList();
|
Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> filter = requests => requests.Where(predicate).ToList();
|
||||||
|
|
||||||
return (filter, requests => (_callsCount is null && filter(requests).Any()) || _callsCount == filter(requests).Count);
|
return (filter, requests => (_callsCount is null && filter(requests).Any()) || _callsCount == filter(requests).Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private (Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> Filter, Func<IReadOnlyList<IRequestMessage>, bool> Condition) BuildFilterAndCondition(Func<IRequestMessage, string?> expression, IStringMatcher matcher)
|
||||||
|
{
|
||||||
|
return BuildFilterAndCondition(r => matcher.IsMatch(expression(r)).IsPerfect());
|
||||||
|
}
|
||||||
|
|
||||||
|
private (Func<IReadOnlyList<IRequestMessage>, IReadOnlyList<IRequestMessage>> Filter, Func<IReadOnlyList<IRequestMessage>, bool> Condition) BuildFilterAndCondition(Func<IRequestMessage, object?> expression, IObjectMatcher matcher)
|
||||||
|
{
|
||||||
|
return BuildFilterAndCondition(r => matcher.IsMatch(expression(r)).IsPerfect());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ namespace WireMock.FluentAssertions
|
|||||||
return new WireMockANumberOfCallsAssertions(Subject, callsCount);
|
return new WireMockANumberOfCallsAssertions(Subject, callsCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ReferenceTypeAssertions{IWireMockServer, WireMockReceivedAssertions}.Identifier"/>
|
/// <inheritdoc />
|
||||||
protected override string Identifier => "wiremockserver";
|
protected override string Identifier => "wiremockserver";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3
src/WireMock.Net.FluentAssertions/Usings.cs
Normal file
3
src/WireMock.Net.FluentAssertions/Usings.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
global using System.Linq;
|
||||||
|
global using FluentAssertions;
|
||||||
|
global using FluentAssertions.Execution;
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<!--<DelaySign>true</DelaySign>-->
|
<!--<DelaySign>true</DelaySign>-->
|
||||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<LangVersion>10</LangVersion>
|
<LangVersion>11</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -36,7 +36,7 @@ internal static class RegexUtils
|
|||||||
{
|
{
|
||||||
if (useRegexExtended)
|
if (useRegexExtended)
|
||||||
{
|
{
|
||||||
var regexExtended = new RegexExtended(pattern, RegexOptions.None, RegexTimeOut);
|
var regexExtended = new RegexExtended(pattern!, RegexOptions.None, RegexTimeOut);
|
||||||
return (true, regexExtended.IsMatch(input));
|
return (true, regexExtended.IsMatch(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Net.Http.Headers;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using WireMock.FluentAssertions;
|
using WireMock.FluentAssertions;
|
||||||
|
using WireMock.Matchers;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
@@ -633,6 +634,194 @@ public class WireMockAssertionsTests : IDisposable
|
|||||||
.AtUrl(_server.Url ?? string.Empty);
|
.AtUrl(_server.Url ?? string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task HaveReceived1Call_WithBodyAsString()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/a").UsingPost().WithBody("x"))
|
||||||
|
.RespondWith(Response.Create().WithBody("A response"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
|
||||||
|
await httpClient.PostAsync($"{server.Url}/a", new StringContent("x"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(1)
|
||||||
|
.Calls()
|
||||||
|
.WithBody("*")
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(1)
|
||||||
|
.Calls()
|
||||||
|
.WithBody("x")
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBody("")
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBody("y")
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task HaveReceived1Call_WithBodyAsJson()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/a").UsingPost().WithBodyAsJson(new { x = "y" }))
|
||||||
|
.RespondWith(Response.Create().WithBody("A response"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
|
||||||
|
await httpClient.PostAsync($"{server.Url}/a", new StringContent(@"{ ""x"": ""y"" }"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(1)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsJson(new { x = "y" })
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(1)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsJson(@"{ ""x"": ""y"" }")
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsJson(new { x = "?" })
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsJson(@"{ ""x"": 1234 }")
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task HaveReceived1Call_WithBodyAsBytes()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/a").UsingPut().WithBody(new byte[] { 100 }))
|
||||||
|
.RespondWith(Response.Create().WithBody("A response"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
|
||||||
|
await httpClient.PutAsync($"{server.Url}/a", new ByteArrayContent(new byte[] { 100 }));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(1)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsBytes(new byte[] { 100 })
|
||||||
|
.And
|
||||||
|
.UsingPut();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsBytes(new byte[0])
|
||||||
|
.And
|
||||||
|
.UsingPut();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBodyAsBytes(new byte[] { 42 })
|
||||||
|
.And
|
||||||
|
.UsingPut();
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task HaveReceived1Call_WithBodyAsString_UsingStringMatcher()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/a").UsingPost().WithBody("x"))
|
||||||
|
.RespondWith(Response.Create().WithBody("A response"));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var httpClient = new HttpClient();
|
||||||
|
|
||||||
|
await httpClient.PostAsync($"{server.Url}/a", new StringContent("x"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(1)
|
||||||
|
.Calls()
|
||||||
|
.WithBody(new ExactMatcher("x"))
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBody(new ExactMatcher(""))
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Should()
|
||||||
|
.HaveReceived(0)
|
||||||
|
.Calls()
|
||||||
|
.WithBody(new ExactMatcher("y"))
|
||||||
|
.And
|
||||||
|
.UsingPost();
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_server?.Stop();
|
_server?.Stop();
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ public class RegexUtilsTests
|
|||||||
[InlineData(null, "test", false, false)]
|
[InlineData(null, "test", false, false)]
|
||||||
[InlineData(".*", "test", true, true)]
|
[InlineData(".*", "test", true, true)]
|
||||||
[InlineData("invalid[", "test", false, false)]
|
[InlineData("invalid[", "test", false, false)]
|
||||||
public void MatchRegex_WithVariousPatterns_ReturnsExpectedResults(
|
public void MatchRegex_WithVariousPatterns_ReturnsExpectedResults(string? pattern, string input, bool expectedIsValid, bool expectedResult)
|
||||||
string? pattern, string input, bool expectedIsValid, bool expectedResult)
|
|
||||||
{
|
{
|
||||||
// Act
|
// Act
|
||||||
var (isValidResult, matchResult) = RegexUtils.MatchRegex(pattern, input);
|
var (isValidResult, matchResult) = RegexUtils.MatchRegex(pattern, input);
|
||||||
@@ -46,8 +45,7 @@ public class RegexUtilsTests
|
|||||||
[InlineData(null, "test", false, false)]
|
[InlineData(null, "test", false, false)]
|
||||||
[InlineData(".*", "test", true, true)]
|
[InlineData(".*", "test", true, true)]
|
||||||
[InlineData("invalid[", "test", false, false)]
|
[InlineData("invalid[", "test", false, false)]
|
||||||
public void MatchRegex_WithVariousPatternsAndExtendedRegex_ReturnsExpectedResults(
|
public void MatchRegex_WithVariousPatternsAndExtendedRegex_ReturnsExpectedResults(string? pattern, string input, bool expectedIsValid, bool expectedResult)
|
||||||
string? pattern, string input, bool expectedIsValid, bool expectedResult)
|
|
||||||
{
|
{
|
||||||
// Act
|
// Act
|
||||||
var (isValidResult, matchResult) = RegexUtils.MatchRegex(pattern, input, useRegexExtended: true);
|
var (isValidResult, matchResult) = RegexUtils.MatchRegex(pattern, input, useRegexExtended: true);
|
||||||
|
|||||||
Reference in New Issue
Block a user