diff --git a/examples/WireMock.Net.ConsoleApplication/Program.cs b/examples/WireMock.Net.ConsoleApplication/Program.cs
index d34c5650..e312b7df 100644
--- a/examples/WireMock.Net.ConsoleApplication/Program.cs
+++ b/examples/WireMock.Net.ConsoleApplication/Program.cs
@@ -18,17 +18,26 @@ namespace WireMock.Net.ConsoleApplication
Console.WriteLine("FluentMockServer running at {0}", server.Port);
server
- .Given(
- Request
- .WithUrl("/*")
- .UsingGet()
- )
- .RespondWith(
- Response
- .WithStatusCode(200)
- .WithHeader("Content-Type", "application/json")
- .WithBody(@"{ ""msg"": ""Hello world!""}")
- );
+ .Given(Request.WithUrl(u => u.Contains("x")).UsingGet())
+ .RespondWith(Response
+ .WithStatusCode(200)
+ .WithHeader("Content-Type", "application/json")
+ .WithBody(@"{ ""result"": ""/x with FUNC 200""}"));
+
+ server
+ .Given(Request.WithUrl("/*").UsingGet())
+ .RespondWith(Response
+ .WithStatusCode(200)
+ .WithHeader("Content-Type", "application/json")
+ .WithBody(@"{ ""msg"": ""Hello world!""}")
+ );
+
+ server
+ .Given(Request.WithUrl("/data").UsingPost().WithBody(b => b.Contains("e")))
+ .RespondWith(Response
+ .WithStatusCode(201)
+ .WithHeader("Content-Type", "application/json")
+ .WithBody(@"{ ""result"": ""data posted with FUNC 201""}"));
server
.Given(Request.WithUrl("/data").UsingPost())
@@ -42,12 +51,11 @@ namespace WireMock.Net.ConsoleApplication
.RespondWith(Response
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json")
- .WithBody(@"{ ""result"": ""data deleted with 201""}"));
+ .WithBody(@"{ ""result"": ""data deleted with 200""}"));
Console.WriteLine("Press any key to stop the server");
Console.ReadKey();
-
Console.WriteLine("Displaying all requests");
var allRequests = server.RequestLogs;
Console.WriteLine(JsonConvert.SerializeObject(allRequests, Formatting.Indented));
diff --git a/src/WireMock/Http/Ports.cs b/src/WireMock/Http/Ports.cs
index 4d5c2e1e..4fa6d268 100644
--- a/src/WireMock/Http/Ports.cs
+++ b/src/WireMock/Http/Ports.cs
@@ -1,16 +1,6 @@
-using System.Diagnostics.CodeAnalysis;
-using System.Net;
+using System.Net;
using System.Net.Sockets;
-[module:
- SuppressMessage("StyleCop.CSharp.DocumentationRules",
- "SA1633:FileMustHaveHeader",
- Justification = "Reviewed. Suppression is OK here, as unknown copyright and company.")]
-[module:
- SuppressMessage("StyleCop.CSharp.DocumentationRules",
- "SA1650:ElementDocumentationMustBeSpelledCorrectly",
- Justification = "Reviewed. Suppression is OK here.")]
-
namespace WireMock.Http
{
///
@@ -24,15 +14,21 @@ namespace WireMock.Http
///
/// The .
///
- /// see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.
- // ReSharper disable once StyleCop.SA1650
+ /// see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.
public static int FindFreeTcpPort()
{
- TcpListener l = new TcpListener(IPAddress.Loopback, 0);
- l.Start();
- int port = ((IPEndPoint)l.LocalEndpoint).Port;
- l.Stop();
- return port;
+ TcpListener tcpListener = null;
+ try
+ {
+ tcpListener = new TcpListener(IPAddress.Loopback, 0);
+ tcpListener.Start();
+
+ return ((IPEndPoint)tcpListener.LocalEndpoint).Port;
+ }
+ finally
+ {
+ tcpListener?.Stop();
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock/Http/TinyHttpServer.cs b/src/WireMock/Http/TinyHttpServer.cs
index 23f3bcbe..38b1fa26 100644
--- a/src/WireMock/Http/TinyHttpServer.cs
+++ b/src/WireMock/Http/TinyHttpServer.cs
@@ -53,13 +53,6 @@ namespace WireMock.Http
{
_httpHandler = httpHandler;
- // .Net Framework is not supportted on XP or Server 2003, so no need for the check
- /*if (!HttpListener.IsSupported)
- {
- Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
- return;
- }*/
-
// Create a listener.
_listener = new HttpListener();
_listener.Prefixes.Add(urlPrefix);
diff --git a/src/WireMock/RequestBodySpec.cs b/src/WireMock/RequestBodySpec.cs
index 5dc7b60f..4e4f5daf 100644
--- a/src/WireMock/RequestBodySpec.cs
+++ b/src/WireMock/RequestBodySpec.cs
@@ -1,3 +1,4 @@
+using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
@@ -29,6 +30,11 @@ namespace WireMock
///
private readonly Regex bodyRegex;
+ ///
+ /// The body function
+ ///
+ private readonly Func bodyFunc;
+
///
/// Initializes a new instance of the class.
///
@@ -41,6 +47,18 @@ namespace WireMock
bodyRegex = new Regex(body);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The body func.
+ ///
+ public RequestBodySpec([NotNull] Func func)
+ {
+ Check.NotNull(func, nameof(func));
+ bodyFunc = func;
+ }
+
///
/// The is satisfied by.
///
@@ -52,7 +70,7 @@ namespace WireMock
///
public bool IsSatisfiedBy(RequestMessage requestMessage)
{
- return bodyRegex.IsMatch(requestMessage.Body);
+ return bodyRegex?.IsMatch(requestMessage.Body) ?? bodyFunc(requestMessage.Body);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock/RequestBuilders/IBodyRequestBuilder.cs b/src/WireMock/RequestBuilders/IBodyRequestBuilder.cs
index b1134a3c..bd7f6504 100644
--- a/src/WireMock/RequestBuilders/IBodyRequestBuilder.cs
+++ b/src/WireMock/RequestBuilders/IBodyRequestBuilder.cs
@@ -1,4 +1,6 @@
-namespace WireMock.RequestBuilders
+using System;
+
+namespace WireMock.RequestBuilders
{
///
/// The BodyRequestBuilder interface.
@@ -15,5 +17,16 @@
/// The .
///
ISpecifyRequests WithBody(string body);
+
+ ///
+ /// The with body.
+ ///
+ ///
+ /// The body function.
+ ///
+ ///
+ /// The .
+ ///
+ ISpecifyRequests WithBody(Func body);
}
}
\ No newline at end of file
diff --git a/src/WireMock/RequestBuilders/IHeadersRequestBuilder.cs b/src/WireMock/RequestBuilders/IHeadersRequestBuilder.cs
index 7595f30a..2de9e2e5 100644
--- a/src/WireMock/RequestBuilders/IHeadersRequestBuilder.cs
+++ b/src/WireMock/RequestBuilders/IHeadersRequestBuilder.cs
@@ -1,4 +1,8 @@
-namespace WireMock.RequestBuilders
+using System;
+using System.Collections.Generic;
+using JetBrains.Annotations;
+
+namespace WireMock.RequestBuilders
{
///
/// The HeadersRequestBuilder interface.
@@ -19,5 +23,16 @@
/// The .
///
IHeadersRequestBuilder WithHeader(string name, string value, bool ignoreCase = true);
+
+ ///
+ /// The with header.
+ ///
+ ///
+ /// The headers func.
+ ///
+ ///
+ /// The .
+ ///
+ IHeadersRequestBuilder WithHeader([NotNull] Func, bool> func);
}
}
\ No newline at end of file
diff --git a/src/WireMock/RequestBuilders/IParamsRequestBuilder.cs b/src/WireMock/RequestBuilders/IParamsRequestBuilder.cs
index 2a639694..40a8f684 100644
--- a/src/WireMock/RequestBuilders/IParamsRequestBuilder.cs
+++ b/src/WireMock/RequestBuilders/IParamsRequestBuilder.cs
@@ -1,4 +1,8 @@
-namespace WireMock.RequestBuilders
+using System;
+using System.Collections.Generic;
+using JetBrains.Annotations;
+
+namespace WireMock.RequestBuilders
{
///
/// The ParametersRequestBuilder interface.
@@ -17,6 +21,17 @@
///
/// The .
///
- ISpecifyRequests WithParam(string key, params string[] values);
+ ISpecifyRequests WithParam([NotNull] string key, params string[] values);
+
+ ///
+ /// The with parameters.
+ ///
+ ///
+ /// The func.
+ ///
+ ///
+ /// The .
+ ///
+ ISpecifyRequests WithParam([NotNull] Func>, bool> func);
}
}
\ No newline at end of file
diff --git a/src/WireMock/RequestBuilders/Request.cs b/src/WireMock/RequestBuilders/Request.cs
index d0e23098..76a4d177 100644
--- a/src/WireMock/RequestBuilders/Request.cs
+++ b/src/WireMock/RequestBuilders/Request.cs
@@ -1,6 +1,8 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using JetBrains.Annotations;
[module:
SuppressMessage("StyleCop.CSharp.ReadabilityRules",
@@ -54,10 +56,25 @@ namespace WireMock.RequestBuilders
///
public static IVerbRequestBuilder WithUrl(string url)
{
- var specs = new List();
- var requests = new Request(specs);
- specs.Add(new RequestUrlSpec(url));
- return requests;
+ var specs = new List { new RequestUrlSpec(url) };
+
+ return new Request(specs);
+ }
+
+ ///
+ /// The with url.
+ ///
+ ///
+ /// The url func.
+ ///
+ ///
+ /// The .
+ ///
+ public static IVerbRequestBuilder WithUrl(Func func)
+ {
+ var specs = new List { new RequestUrlSpec(func) };
+
+ return new Request(specs);
}
///
@@ -71,10 +88,25 @@ namespace WireMock.RequestBuilders
///
public static IVerbRequestBuilder WithPath(string path)
{
- var specs = new List();
- var requests = new Request(specs);
- specs.Add(new RequestPathSpec(path));
- return requests;
+ var specs = new List { new RequestPathSpec(path) };
+
+ return new Request(specs);
+ }
+
+ ///
+ /// The with path.
+ ///
+ ///
+ /// The path func.
+ ///
+ ///
+ /// The .
+ ///
+ public static IVerbRequestBuilder WithPath([NotNull] Func func)
+ {
+ var specs = new List { new RequestPathSpec(func) };
+
+ return new Request(specs);
}
///
@@ -178,6 +210,21 @@ namespace WireMock.RequestBuilders
return this;
}
+ ///
+ /// The with body.
+ ///
+ ///
+ /// The body function.
+ ///
+ ///
+ /// The .
+ ///
+ public ISpecifyRequests WithBody(Func func)
+ {
+ _requestSpecs.Add(new RequestBodySpec(func));
+ return this;
+ }
+
///
/// The with parameters.
///
@@ -196,6 +243,21 @@ namespace WireMock.RequestBuilders
return this;
}
+ ///
+ /// The with parameters.
+ ///
+ ///
+ /// The func.
+ ///
+ ///
+ /// The .
+ ///
+ public ISpecifyRequests WithParam(Func>, bool> func)
+ {
+ _requestSpecs.Add(new RequestParamSpec(func));
+ return this;
+ }
+
///
/// The with header.
///
@@ -214,5 +276,20 @@ namespace WireMock.RequestBuilders
_requestSpecs.Add(new RequestHeaderSpec(name, value, ignoreCase));
return this;
}
+
+ ///
+ /// The with header.
+ ///
+ ///
+ /// The func.
+ ///
+ ///
+ /// The .
+ ///
+ public IHeadersRequestBuilder WithHeader(Func, bool> func)
+ {
+ _requestSpecs.Add(new RequestHeaderSpec(func));
+ return this;
+ }
}
}
diff --git a/src/WireMock/RequestHeaderSpec.cs b/src/WireMock/RequestHeaderSpec.cs
index 43e70172..b8bf9e47 100644
--- a/src/WireMock/RequestHeaderSpec.cs
+++ b/src/WireMock/RequestHeaderSpec.cs
@@ -1,6 +1,9 @@
-using System.Diagnostics.CodeAnalysis;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
+using WireMock.Validation;
[module:
SuppressMessage("StyleCop.CSharp.ReadabilityRules",
@@ -33,6 +36,11 @@ namespace WireMock
///
private readonly Regex patternRegex;
+ ///
+ /// The header function
+ ///
+ private readonly Func, bool> headerFunc;
+
///
/// Initializes a new instance of the class.
///
@@ -49,6 +57,18 @@ namespace WireMock
patternRegex = ignoreCase ? new Regex(pattern, RegexOptions.IgnoreCase) : new Regex(pattern);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The func.
+ ///
+ public RequestHeaderSpec([NotNull] Func, bool> func)
+ {
+ Check.NotNull(func, nameof(func));
+ headerFunc = func;
+ }
+
///
/// The is satisfied by.
///
@@ -58,8 +78,11 @@ namespace WireMock
///
/// The .
///
- public bool IsSatisfiedBy([NotNull] RequestMessage requestMessage)
+ public bool IsSatisfiedBy(RequestMessage requestMessage)
{
+ if (patternRegex == null)
+ return headerFunc(requestMessage.Headers);
+
string headerValue = requestMessage.Headers[name];
return patternRegex.IsMatch(headerValue);
}
diff --git a/src/WireMock/RequestMessage.cs b/src/WireMock/RequestMessage.cs
index 2ac15c19..224b5152 100644
--- a/src/WireMock/RequestMessage.cs
+++ b/src/WireMock/RequestMessage.cs
@@ -18,8 +18,7 @@ using System.Linq;
SuppressMessage("StyleCop.CSharp.DocumentationRules",
"SA1650:ElementDocumentationMustBeSpelledCorrectly",
Justification = "Reviewed. Suppression is OK here.")]
-// ReSharper disable ArrangeThisQualifier
-// ReSharper disable InconsistentNaming
+
namespace WireMock
{
///
@@ -30,7 +29,7 @@ namespace WireMock
///
/// The _params.
///
- private readonly Dictionary> _params = new Dictionary>();
+ private readonly IDictionary> _params = new Dictionary>();
///
/// Initializes a new instance of the class.
@@ -50,7 +49,7 @@ namespace WireMock
///
/// The headers.
///
- public RequestMessage(string path, string query, string verb, string body, IDictionary headers)
+ public RequestMessage(string path, string query, string verb, string body, IDictionary headers = null)
{
if (!string.IsNullOrEmpty(query))
{
@@ -72,12 +71,14 @@ namespace WireMock
dict[key].Add(term.Split('=')[1]);
return dict;
});
+
+ Parameters = _params;
}
Path = path;
- Headers = headers; //.ToDictionary(kv => kv.Key.ToLower(), kv => kv.Value.ToLower());
+ Headers = headers;
Verb = verb.ToLower();
- Body = body?.Trim() ?? string.Empty;
+ Body = body;
}
///
@@ -111,6 +112,11 @@ namespace WireMock
///
public IDictionary Headers { get; }
+ ///
+ /// Gets the parameters.
+ ///
+ public IDictionary> Parameters { get; }
+
///
/// Gets the body.
///
@@ -130,4 +136,4 @@ namespace WireMock
return _params.ContainsKey(key) ? _params[key] : new List();
}
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock/RequestParamSpec.cs b/src/WireMock/RequestParamSpec.cs
index 065f6658..e1bc2100 100644
--- a/src/WireMock/RequestParamSpec.cs
+++ b/src/WireMock/RequestParamSpec.cs
@@ -1,7 +1,9 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using JetBrains.Annotations;
+using WireMock.Validation;
[module:
SuppressMessage("StyleCop.CSharp.ReadabilityRules",
@@ -15,8 +17,7 @@ using JetBrains.Annotations;
SuppressMessage("StyleCop.CSharp.DocumentationRules",
"SA1633:FileMustHaveHeader",
Justification = "Reviewed. Suppression is OK here, as unknown copyright and company.")]
-// ReSharper disable ArrangeThisQualifier
-// ReSharper disable InconsistentNaming
+
namespace WireMock
{
///
@@ -32,7 +33,9 @@ namespace WireMock
///
/// The _values.
///
- private readonly List _values;
+ private readonly IEnumerable _values;
+
+ private readonly Func>, bool> _func;
///
/// Initializes a new instance of the class.
@@ -43,12 +46,27 @@ namespace WireMock
///
/// The values.
///
- public RequestParamSpec(string key, List values)
+ public RequestParamSpec([NotNull] string key, [NotNull] IEnumerable values)
{
+ Check.NotNull(key, nameof(key));
+ Check.NotNull(values, nameof(values));
+
_key = key;
_values = values;
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The func.
+ ///
+ public RequestParamSpec([NotNull] Func>, bool> func)
+ {
+ Check.NotNull(func, nameof(func));
+ _func = func;
+ }
+
///
/// The is satisfied by.
///
@@ -58,9 +76,14 @@ namespace WireMock
///
/// The .
///
- public bool IsSatisfiedBy([NotNull] RequestMessage requestMessage)
+ public bool IsSatisfiedBy(RequestMessage requestMessage)
{
- return requestMessage.GetParameter(_key).Intersect(_values).Count() == _values.Count;
+ if (_func != null)
+ {
+ return _func(requestMessage.Parameters);
+ }
+
+ return requestMessage.GetParameter(_key).Intersect(_values).Count() == _values.Count();
}
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock/RequestPathSpec.cs b/src/WireMock/RequestPathSpec.cs
index c1e56f60..6a83848e 100644
--- a/src/WireMock/RequestPathSpec.cs
+++ b/src/WireMock/RequestPathSpec.cs
@@ -1,4 +1,5 @@
-using System.Diagnostics.CodeAnalysis;
+using System;
+using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using WireMock.Validation;
@@ -15,8 +16,7 @@ using WireMock.Validation;
SuppressMessage("StyleCop.CSharp.DocumentationRules",
"SA1633:FileMustHaveHeader",
Justification = "Reviewed. Suppression is OK here, as unknown copyright and company.")]
-// ReSharper disable ArrangeThisQualifier
-// ReSharper disable InconsistentNaming
+
namespace WireMock
{
///
@@ -25,9 +25,14 @@ namespace WireMock
public class RequestPathSpec : ISpecifyRequests
{
///
- /// The _path.
+ /// The pathRegex.
///
- private readonly Regex _path;
+ private readonly Regex pathRegex;
+
+ ///
+ /// The url function
+ ///
+ private readonly Func pathFunc;
///
/// Initializes a new instance of the class.
@@ -38,7 +43,19 @@ namespace WireMock
public RequestPathSpec([NotNull, RegexPattern] string path)
{
Check.NotNull(path, nameof(path));
- _path = new Regex(path);
+ pathRegex = new Regex(path);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The url func.
+ ///
+ public RequestPathSpec([NotNull] Func func)
+ {
+ Check.NotNull(func, nameof(func));
+ pathFunc = func;
}
///
@@ -50,9 +67,9 @@ namespace WireMock
///
/// The .
///
- public bool IsSatisfiedBy([NotNull] RequestMessage requestMessage)
+ public bool IsSatisfiedBy(RequestMessage requestMessage)
{
- return _path.IsMatch(requestMessage.Path);
+ return pathRegex?.IsMatch(requestMessage.Path) ?? pathFunc(requestMessage.Path);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock/RequestUrlSpec.cs b/src/WireMock/RequestUrlSpec.cs
index e0abe499..06f8d981 100644
--- a/src/WireMock/RequestUrlSpec.cs
+++ b/src/WireMock/RequestUrlSpec.cs
@@ -1,4 +1,5 @@
-using System.Diagnostics.CodeAnalysis;
+using System;
+using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;
using System.Text.RegularExpressions;
using WireMock.Validation;
@@ -29,6 +30,11 @@ namespace WireMock
///
private readonly Regex urlRegex;
+ ///
+ /// The url function
+ ///
+ private readonly Func urlFunc;
+
///
/// Initializes a new instance of the class.
///
@@ -41,6 +47,18 @@ namespace WireMock
urlRegex = new Regex(url);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The url func.
+ ///
+ public RequestUrlSpec(Func func)
+ {
+ Check.NotNull(func, nameof(func));
+ urlFunc = func;
+ }
+
///
/// The is satisfied by.
///
@@ -52,7 +70,7 @@ namespace WireMock
///
public bool IsSatisfiedBy(RequestMessage requestMessage)
{
- return urlRegex.IsMatch(requestMessage.Url);
+ return urlRegex?.IsMatch(requestMessage.Url) ?? urlFunc(requestMessage.Url);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock/ResponseMessage.cs b/src/WireMock/ResponseMessage.cs
index 24963cbe..4836aa17 100644
--- a/src/WireMock/ResponseMessage.cs
+++ b/src/WireMock/ResponseMessage.cs
@@ -28,16 +28,6 @@ namespace WireMock
///
private readonly IDictionary _headers = new ConcurrentDictionary();
- ///
- /// The status code.
- ///
- private volatile int statusCode = 200;
-
- ///
- /// The body.
- ///
- private volatile string body;
-
///
/// Gets the headers.
///
@@ -46,34 +36,12 @@ namespace WireMock
///
/// Gets or sets the status code.
///
- public int StatusCode
- {
- get
- {
- return statusCode;
- }
-
- set
- {
- statusCode = value;
- }
- }
+ public int StatusCode { get; set; } = 200;
///
/// Gets or sets the body.
///
- public string Body
- {
- get
- {
- return body;
- }
-
- set
- {
- body = value;
- }
- }
+ public string Body { get; set; }
///
/// The add header.
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.cs b/test/WireMock.Net.Tests/FluentMockServerTests.cs
index 2c15b19a..05f85155 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.cs
@@ -86,7 +86,7 @@ namespace WireMock.Net.Tests
Check.That(_server.RequestLogs).HasSize(1);
var requestLogged = _server.RequestLogs.First();
Check.That(requestLogged.Verb).IsEqualTo("get");
- Check.That(requestLogged.Body).IsEmpty();
+ Check.That(requestLogged.Body).IsNull();
}
[Test]
diff --git a/test/WireMock.Net.Tests/RequestsTests.cs b/test/WireMock.Net.Tests/RequestsTests.cs
index 9d138923..d754f90a 100644
--- a/test/WireMock.Net.Tests/RequestsTests.cs
+++ b/test/WireMock.Net.Tests/RequestsTests.cs
@@ -265,6 +265,19 @@ namespace WireMock.Net.Tests
Check.That(spec.IsSatisfiedBy(request)).IsTrue();
}
+ [Test]
+ public void Should_specify_requests_matching_given_params_func()
+ {
+ // given
+ var spec = Request.WithPath("/foo").WithParam(p => p.ContainsKey("bar") && (p["bar"].Contains("1") || p["bar"].Contains("2")));
+
+ // when
+ var request = new RequestMessage("/foo", "bar=1&bar=2", "Get", "Hello world!", new Dictionary());
+
+ // then
+ Check.That(spec.IsSatisfiedBy(request)).IsTrue();
+ }
+
[Test]
public void Should_exclude_requests_not_matching_given_params()
{