Skip to content

Request Matching

Bernard Niset edited this page Dec 18, 2022 · 2 revisions

(This documentation is adapted from the original documentation of WireMock.)

Mimus Serve supports matching of requests to stubs and verification queries using the following attributes:

  • URL
  • HTTP Method
  • Query parameters
  • Headers
  • Cookies
  • Request body

Soon, we will also support:

  • Basic authentication (a special case of header matching)
  • Multipart/form-data

URL matching

URLs can be matched either by equality or by regular expression. You also have a choice of whether to match just the path part of the URL or the path and query together.

It is usually preferable to match on path only if you want to match multiple query parameters in an order invariant manner.

Equality matching on path and query

{
  "request": {
    "url": "/your/url?and=query"
    ...
  },
  ...
}

Regex matching on path and query

{
  "request": {
    "urlPattern": "/your/([a-z]*)\\?and=query"
    ...
  },
  ...
}

Equality matching on the path only

{
  "request": {
    "urlPath": "/your/url"
    ...
  },
  ...
}

Regex matching on the path only

{
  "request": {
    "urlPathPattern": "/your/([a-z]*)"
    ...
  },
  ...
}

Matching other attributes

All request attributes other than the URL can be matched using the following set of operators.

This works for the following matching attributes:

  • Query parameters
  • Headers
  • Cookies
  • Request Body

Equality

Deems a match if the entire attribute value equals the expected value.

{
  "request": {
    ...
    "headers": {
      "Content-Type": {
        "equalTo": "application/json"
      }
    }
    ...
  },
  ...
}

Case-insensitive equality

Deems a match if the entire attribute value equals the expected value, ignoring case.

{
  "request": {
    ...
    "headers": {
      "Content-Type": {
        "equalTo": "application/json",
        "caseInsensitive": true
      }
    }
    ...
  },
  ...
}

Binary Equality

Deems a match if the entire binary attribute value equals the expected value. Unlike the above equalTo operator, this compares byte arrays (or their equivalent base64 representation).

{
  "request": {
    ...
    "bodyPatterns" : [{
        "binaryEqualTo" : "AQID" // Base 64
    }]
    ...
  },
  ...
}

Substring (contains)

Deems a match if the a portion of the attribute value equals the expected value.

{
  "request": {
    ...
    "cookies" : {
      "my_profile" : {
        "contains" : "[email protected]"
      }
    }
    ...
  },
  ...
}

Regular expression

Deems a match if the entire attribute value matched the expected regular expression.

{
  "request": {
    ...
    "queryParameters" : {
      "search_term" : {
        "matches" : "^(.*)Mimus Serve([A-Za-z]+)$"
      }
    }
    ...
  },
  ...
}

It is also possible to perform a negative match i.e. the match succeeds when the attribute value does not match the regex:

{
  "request": {
    ...
    "queryParameters" : {
      "search_term" : {
        "doesNotMatch" : "^(.*)Mimus Serve([A-Za-z]+)$"
      }
    }
    ...
  },
  ...
}

JSON equality

Deems a match if the attribute (most likely the request body in practice) is valid JSON and is a semantic match for the expected value.

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "equalToJson" : { "total_results": 4 }
    } ]
    ...
  },
  ...
}

JSON with string literal:

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "equalToJson" : "{ \"total_results\": 4 }"
    } ]
    ...
  },
  ...
}

Less strict matching

By default different array orderings and additional object attributes will trigger a non-match. However, both of these conditions can be disabled individually.

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "equalToJson" : "{ \"total_results\": 4  }",
      "ignoreArrayOrder" : true,
      "ignoreExtraElements" : true
    } ]
    ...
  },
  ...
}

JSON Path

Deems a match if the attribute value is valid JSON and matches the JSON Path expression supplied. A JSON body will be considered to match a path expression if the expression returns either a non-null single value (string, integer etc.), or a non-empty object or array.

Presence matching

Deems a match if the attribute value is present in the JSON.

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$.name"
    } ]
    ...
  },
  ...
}

Request body example:

// matching
{ "name": "Mimus Serve" }
// not matching
{ "price": 15 }

Equality matching

Deems a match if the attribute value equals the expected value.

JSON:

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$.things[?(@.name == 'RequiredThing')]"
    } ]
    ...
  },
  ...
}

Request body example:

// matching
{ "things": { "name": "RequiredThing" } }
{ "things": [ { "name": "RequiredThing" }, { "name": "Mimus Serve" } ] }
// not matching
{ "price": 15 }
{ "things": { "name": "Mimus Serve" } }

Regex matching

Deems a match if the attribute value matches the regex expected value.

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$.things[?(@.name =~ /Required.*/i)]"
    } ]
    ...
  },
  ...
}

Request body example:

// matching
{ "things": { "name": "RequiredThing" } }
{ "things": [ { "name": "Required" }, { "name": "Mimus Serve" } ] }
// not matching
{ "price": 15 }
{ "things": { "name": "Mimus Serve" } }
{ "things": [ { "name": "Thing" }, { "name": "Mimus Serve" } ] }

Size matching

Deems a match if the attribute size matches the expected size.

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$[?(@.things.size() == 2)]"
    } ]
    ...
  },
  ...
}

Request body example:

// matching
{ "things": [ { "name": "RequiredThing" }, { "name": "Mimus Serve" } ] }
// not matching
{ "things": [ { "name": "RequiredThing" } ] }

Nested value matching

The JSONPath matcher can be combined with another matcher, such that the value returned from the JSONPath query is evaluated against it:

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "matchesJsonPath" : {
         "expression": "$..todoItem",
         "contains": "wash"
      }
    } ]
    ...
  },
  ...
}

Since Mimus Serve's matching operators all work on strings, the value selected by the JSONPath expression will be coerced to a string before the match is evaluated. This true even if the returned value is an object or array. A benefit of this is that this allows a sub-document to be selected using JSONPath, then matched using the equalToJson operator. E.g. for the following request body:

{
  "outer": {
    "inner": 42
  }
}

The following will match:

{
  "request": {
    ...
    "bodyPatterns" : [ {
      "matchesJsonPath" : {
         "expression": "$.outer",
         "equalToJson": "{ \"inner\": 42 }"
      }
    } ]
    ...
  },
  ...
}

Absence

Deems a match if the attribute specified is absent from the request.

{
  "request": {
    ...
    "headers" : {
      "X-Absent" : {
        "absent" : true
      }
    },
    "queryParameters" : {
      "search_term" : {
        "absent" : true
      }
    },
    "cookies" : {
      "session" : {
        "absent" : true
      }
    }
    ...
  },
  ...
}

Presence

Deems a match if the attribute specified is present in the request.

{
  "request": {
    ...
        "queryParameters" : {
      "search_term" : {
        "present" : true
      }
    }
    ...
  },
  ...
}