mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-18 23:33:47 +01:00
Support for string and object in JsonMatcher. (#157)
* JsonMatcher (#154) * small update in example code
This commit is contained in:
@@ -57,12 +57,22 @@ namespace WireMock.Net.ConsoleApplication
|
||||
server
|
||||
.Given(Request
|
||||
.Create()
|
||||
.WithPath("/jsonbodytest")
|
||||
.WithPath("/jsonbodytest1")
|
||||
.WithBody(new JsonMatcher("{ \"x\": 42, \"s\": \"s\" }"))
|
||||
.UsingPost())
|
||||
.WithGuid("debaf408-3b23-4c04-9d18-ef1c020e79f2")
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(@"{ ""result"": ""jsonbodytest"" }"));
|
||||
.WithBody(@"{ ""result"": ""jsonbodytest1"" }"));
|
||||
|
||||
server
|
||||
.Given(Request
|
||||
.Create()
|
||||
.WithPath("/jsonbodytest2")
|
||||
.WithBody(new JsonMatcher(new { x = 42, s = "s" }))
|
||||
.UsingPost())
|
||||
.WithGuid("debaf408-3b23-4c04-9d18-ef1c020e79f3")
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(@"{ ""result"": ""jsonbodytest2"" }"));
|
||||
|
||||
server
|
||||
.Given(Request
|
||||
@@ -77,7 +87,6 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.Given(Request.Create().WithPath("/headers", "/headers_test").UsingPost().WithHeader("Content-Type", "application/json*"))
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(201)
|
||||
//.WithHeader("MyHeader", "application/json", "application/json2")
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { result = "data:headers posted with 201" }));
|
||||
|
||||
@@ -184,8 +193,6 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithStatusCode(HttpStatusCode.Unauthorized)
|
||||
.WithBody(@"{ ""result"": ""api-key missing""}"));
|
||||
|
||||
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/nobody").UsingGet())
|
||||
.RespondWith(Response.Create().WithDelay(TimeSpan.FromSeconds(1))
|
||||
@@ -195,7 +202,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.Given(Request.Create().WithPath("/partial").UsingPost().WithBody(new SimMetricsMatcher(new[] { "cat", "dog" })))
|
||||
.RespondWith(Response.Create().WithStatusCode(200).WithBody("partial = 200"));
|
||||
|
||||
// http://localhost:8080/any/any?start=1000&stop=1&stop=2
|
||||
// http://localhost:8080/trans?start=1000&stop=1&stop=2
|
||||
server
|
||||
.Given(Request.Create().WithPath("/trans").UsingGet())
|
||||
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
|
||||
@@ -203,6 +210,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithStatusCode(200)
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithHeader("Transformed-Postman-Token", "token is {{request.headers.Postman-Token}}")
|
||||
.WithHeader("xyz_{{request.headers.Postman-Token}}", "token is {{request.headers.Postman-Token}}")
|
||||
.WithBody(@"{""msg"": ""Hello world CATCH-ALL on /*, {{request.path}}, bykey={{request.query.start}}, bykey={{request.query.stop}}, byidx0={{request.query.stop.[0]}}, byidx1={{request.query.stop.[1]}}"" }")
|
||||
.WithTransformer()
|
||||
.WithDelay(TimeSpan.FromMilliseconds(100))
|
||||
|
||||
@@ -42,8 +42,18 @@
|
||||
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
@@ -53,6 +63,7 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="log4net.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
11
examples/WireMock.Net.StandAlone.Net452/app.config
Normal file
11
examples/WireMock.Net.StandAlone.Net452/app.config
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="log4net" version="2.0.8" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.4" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -11,19 +11,14 @@
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value. Used by <see cref="Matchers.JsonMatcher"/>.
|
||||
/// Gets or sets the pattern. Can be a string (default) or an object;
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
public object Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pattern.
|
||||
/// Gets or sets the patterns. Can be array of strings (default) or an array of objects;
|
||||
/// </summary>
|
||||
public string Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the patterns.
|
||||
/// </summary>
|
||||
public string[] Patterns { get; set; }
|
||||
public object[] Patterns { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ignore case.
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
public interface IValueMatcher: IObjectMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// Gets the value (can be a string or an obejct).
|
||||
/// </summary>
|
||||
/// <returns>Value</returns>
|
||||
string GetValue();
|
||||
object Value { get; }
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,8 @@ namespace WireMock.Matchers
|
||||
/// </summary>
|
||||
public class JsonMatcher : IValueMatcher
|
||||
{
|
||||
private readonly string _value;
|
||||
/// <inheritdoc cref="IValueMatcher.Value"/>
|
||||
public object Value { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => "JsonMatcher";
|
||||
@@ -21,22 +22,43 @@ namespace WireMock.Matchers
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to check for equality.</param>
|
||||
/// <param name="value">The string value to check for equality.</param>
|
||||
public JsonMatcher([NotNull] string value) : this(MatchBehaviour.AcceptOnMatch, value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="value">The object value to check for equality.</param>
|
||||
public JsonMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="value">The value to check for equality.</param>
|
||||
/// <param name="value">The string value to check for equality.</param>
|
||||
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value)
|
||||
{
|
||||
Check.NotNull(value, nameof(value));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
_value = value;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="value">The object value to check for equality.</param>
|
||||
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
|
||||
{
|
||||
Check.NotNull(value, nameof(value));
|
||||
|
||||
MatchBehaviour = matchBehaviour;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
@@ -48,9 +70,15 @@ namespace WireMock.Matchers
|
||||
try
|
||||
{
|
||||
// Check if JToken or object
|
||||
JToken jtoken = input is JToken token ? token : JObject.FromObject(input);
|
||||
JToken jtokenInput = input is JToken tokenInput ? tokenInput : JObject.FromObject(input);
|
||||
|
||||
match = JToken.DeepEquals(JToken.Parse(_value), jtoken);
|
||||
// Check if JToken or string or object
|
||||
JToken jtokenValue =
|
||||
Value is JToken tokenValue ? tokenValue :
|
||||
Value is string stringValue ? JToken.Parse(stringValue) :
|
||||
JObject.FromObject(input);
|
||||
|
||||
match = JToken.DeepEquals(jtokenValue, jtokenInput);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
@@ -60,8 +88,5 @@ namespace WireMock.Matchers
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IValueMatcher.GetValue"/>
|
||||
public string GetValue() => _value;
|
||||
}
|
||||
}
|
||||
@@ -21,28 +21,28 @@ namespace WireMock.Serialization
|
||||
string matcherName = parts[0];
|
||||
string matcherType = parts.Length > 1 ? parts[1] : null;
|
||||
|
||||
string[] patterns = matcher.Patterns ?? new[] { matcher.Pattern };
|
||||
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new [] { matcher.Pattern as string };
|
||||
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
||||
|
||||
switch (matcherName)
|
||||
{
|
||||
case "ExactMatcher":
|
||||
return new ExactMatcher(matchBehaviour, patterns);
|
||||
return new ExactMatcher(matchBehaviour, stringPatterns);
|
||||
|
||||
case "RegexMatcher":
|
||||
return new RegexMatcher(matchBehaviour, patterns, matcher.IgnoreCase == true);
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
|
||||
|
||||
case "JsonMatcher":
|
||||
return new JsonMatcher(matchBehaviour, matcher.Pattern);
|
||||
|
||||
case "JsonPathMatcher":
|
||||
return new JsonPathMatcher(matchBehaviour, patterns);
|
||||
return new JsonPathMatcher(matchBehaviour, stringPatterns);
|
||||
|
||||
case "XPathMatcher":
|
||||
return new XPathMatcher(matchBehaviour, matcher.Pattern);
|
||||
return new XPathMatcher(matchBehaviour, (string) matcher.Pattern);
|
||||
|
||||
case "WildcardMatcher":
|
||||
return new WildcardMatcher(matchBehaviour, patterns, matcher.IgnoreCase == true);
|
||||
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
|
||||
|
||||
case "SimMetricsMatcher":
|
||||
SimMetricType type = SimMetricType.Levenstein;
|
||||
@@ -51,7 +51,7 @@ namespace WireMock.Serialization
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||
}
|
||||
|
||||
return new SimMetricsMatcher(matchBehaviour, matcher.Pattern, type);
|
||||
return new SimMetricsMatcher(matchBehaviour, (string) matcher.Pattern, type);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
||||
@@ -70,9 +70,13 @@ namespace WireMock.Serialization
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] patterns = matcher is IStringMatcher stringMatcher ?
|
||||
stringMatcher.GetPatterns() :
|
||||
matcher is IValueMatcher valueMatcher ? new[] { valueMatcher.GetValue() } : new string[0];
|
||||
// If the matcher is a IStringMatcher, get the patterns.
|
||||
// If the matcher is a IValueMatcher, get the value (can be string or object).
|
||||
// Else empty array
|
||||
object[] patterns = matcher is IStringMatcher stringMatcher ?
|
||||
stringMatcher.GetPatterns().Cast<object>().ToArray() :
|
||||
matcher is IValueMatcher valueMatcher ? new[] { valueMatcher.Value } :
|
||||
new object[0];
|
||||
bool? ignorecase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : (bool?)null;
|
||||
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : (bool?)null;
|
||||
|
||||
|
||||
@@ -238,7 +238,11 @@ namespace WireMock.Server
|
||||
}
|
||||
});
|
||||
|
||||
if (requestMessage.Body != null)
|
||||
if (requestMessage.BodyAsJson != null)
|
||||
{
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));
|
||||
}
|
||||
else if (requestMessage.Body != null)
|
||||
{
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace WireMock.Net.Tests
|
||||
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
|
||||
string json = File.ReadAllText(folder);
|
||||
|
||||
string responseBodyFilePath = Path.Combine(GetCurrentFolder(), "ResponseBodyFiles", "responsebody.json");
|
||||
string responseBodyFilePath = Path.Combine(GetCurrentFolder(), "responsebody.json");
|
||||
|
||||
dynamic jsonObj = JsonConvert.DeserializeObject(json);
|
||||
jsonObj["Response"]["BodyAsFile"] = responseBodyFilePath;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace WireMock.Net.Tests.Matchers
|
||||
var matcher = new JsonMatcher("{}");
|
||||
|
||||
// Act
|
||||
string value = matcher.GetValue();
|
||||
object value = matcher.Value;
|
||||
|
||||
// Assert
|
||||
Check.That(value).Equals("{}");
|
||||
@@ -62,7 +62,39 @@ namespace WireMock.Net.Tests.Matchers
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_JObject()
|
||||
public void JsonMatcher_IsMatch_JObject1()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonMatcher(new { Id = 1, Name = "test" });
|
||||
|
||||
// Act
|
||||
var jobject = new JObject
|
||||
{
|
||||
{ "Id", new JValue(1) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
double match = matcher.IsMatch(jobject);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_JObject2()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonMatcher(new { Id = 1, Name = "test" });
|
||||
|
||||
// Act
|
||||
var jobject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
double match = matcher.IsMatch(jobject);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_JObjectAsString()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonMatcher("{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
@@ -80,7 +112,7 @@ namespace WireMock.Net.Tests.Matchers
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_JObject_RejectOnMatch()
|
||||
public void JsonMatcher_IsMatch_JObjectAsString_RejectOnMatch()
|
||||
{
|
||||
// Assign
|
||||
var matcher = new JsonMatcher(MatchBehaviour.RejectOnMatch, "{ \"Id\" : 1, \"Name\" : \"Test\" }");
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="ResponseBodyFiles\responsebody.json">
|
||||
<None Update="responsebody.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\00000002-ee28-4f29-ae63-1ac9b0802d86.json">
|
||||
|
||||
Reference in New Issue
Block a user