mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 13:00:33 +01:00
Add WithBodyAsType to RequestMatcher (#1388)
* Add WithBody<T> * . * t * t2
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request body matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageBodyMatcher<T> : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The body data function for type T
|
||||
/// </summary>
|
||||
public Func<T?, bool>? Func { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<T?, bool> func)
|
||||
{
|
||||
Func = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var (score, exception) = CalculateMatchScore(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private MatchResult CalculateMatchScore(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Func != null)
|
||||
{
|
||||
if (requestMessage.BodyData?.BodyAsJson is JObject jsonObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bodyAsT = jsonObject.ToObject<T>();
|
||||
return MatchScores.ToScore(Func(bodyAsT));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new MatchResult(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -34,13 +34,6 @@ public partial class Request
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsJson(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
var matcher = body as IMatcher ?? new JsonMatcher(matchBehaviour, body);
|
||||
return WithBody([matcher]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBody(IMatcher matcher)
|
||||
{
|
||||
@@ -98,4 +91,20 @@ public partial class Request
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(Guard.NotNull(func)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsJson(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
var matcher = body as IMatcher ?? new JsonMatcher(matchBehaviour, body);
|
||||
return WithBody([matcher]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsType<T>(Func<T?, bool> func)
|
||||
{
|
||||
Guard.NotNull(func);
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher<T>(func));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
public static IRequestBuilder Create()
|
||||
{
|
||||
return new Request(new List<IRequestMatcher>());
|
||||
return new Request([]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -80,6 +80,14 @@ public interface IBodyRequestBuilder : IMultiPartRequestBuilder
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<object?, bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (type)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type.</typeparam>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBodyAsType<T>(Func<T?, bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (BodyData object)
|
||||
/// </summary>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
@@ -72,15 +73,17 @@ public class RequestBuilderWithBodyTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Request_WithBody_FuncJson()
|
||||
public void Request_WithBody_FuncObject()
|
||||
{
|
||||
// Assign
|
||||
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b != null);
|
||||
var requestBuilder = Request.Create()
|
||||
.UsingAnyMethod()
|
||||
.WithBody(b => b != null);
|
||||
|
||||
// Act
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = 123,
|
||||
BodyAsJson = JObject.Parse("""{ "X": 123, "Y": "a" }"""),
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
@@ -90,6 +93,57 @@ public class RequestBuilderWithBodyTests
|
||||
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("""{ "X": 123, "Y": "a" }""", 1.0)]
|
||||
[InlineData("""{ "X": 123, "Y": "b" }""", 0.0)]
|
||||
public void Request_WithBodyAsType_Func(string json, double expected)
|
||||
{
|
||||
// Assign
|
||||
var requestBuilder = Request.Create()
|
||||
.UsingAnyMethod()
|
||||
.WithBodyAsType<FuncType>(ft => ft != null && ft.X == 123 && ft.Y == "a");
|
||||
|
||||
// Act
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(json),
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
// Assert
|
||||
var requestMatchResult = new RequestMatchResult();
|
||||
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Request_WithBodyAsType_Func_IncorrectType()
|
||||
{
|
||||
// Assign
|
||||
var requestBuilder = Request.Create()
|
||||
.UsingAnyMethod()
|
||||
.WithBodyAsType<Version>(ft => ft != null);
|
||||
|
||||
// Act
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse("""{ "X": 123, "Y": "a" }"""),
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
// Assert
|
||||
var requestMatchResult = new RequestMatchResult();
|
||||
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(0.0);
|
||||
}
|
||||
|
||||
private class FuncType
|
||||
{
|
||||
public int X { get; set; } = 42;
|
||||
|
||||
public string Y { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Request_WithBody_FuncFormUrlEncoded()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user