How WireMock matching criteria works?

23 Views Asked by At

I created some mappings using Spring Cloud Contracts. I defined two contracts, they are basically the same in the request part, they have the same url path but one of them has a query parameter defined.

The problem arises when I run my integration tests using WireMock in the consumer side. Wiremock is loading the two generated mappings correctly but when I send a request with the query param is returning the response corresponding the mapping WITHOUT the query param.

After this, I added a priority of 1 to the more specific one (with query param) and priority of 2 to the other and now is working as expected but honestly, that solution was instinctive, I don't understand why is working.

It's like if priority has more precedence in the criteria than query params and that for me is not logical. Query param should be a better discriminator.

The more specific mapping:

{
  "id" : "413e922d-f92d-4a2c-8b2a-56dff17e7c4c",
  "request" : {
    "urlPath" : "/fetch-recommendations",
    "method" : "PUT",
    "headers" : {
      "Content-Type" : {
        "equalTo" : "application/json"
      }
    },
    "queryParameters" : {
      "exclusions" : {
        "equalTo" : "Platformer"
      }
    },
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$[?(@.['userId'] =~ /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/)]"
    }, {
      "matchesJsonPath" : "$.['preferredGenres'][?(@ == 'Platformer')]"
    }, {
      "matchesJsonPath" : "$.['preferredGenres'][?(@ == 'Stealth')]"
    }, {
      "matchesJsonPath" : "$.['preferredGenres'][?(@ == 'Adventure')]"
    } ]
  },
  "response" : {
    "status" : 200,
    "body" : "{\"videogames\":[{\"name\":\"Red Dead Redemption\",\"genre\":\"Adventure\"}]}",
    "headers" : {
      "Content-Type" : "application/json"
    },
    "transformers" : [ "response-template", "spring-cloud-contract" ]
  },
  "uuid" : "413e922d-f92d-4a2c-8b2a-56dff17e7c4c",
  "priority" : 1
}

The one without the query param:

{
  "id" : "49330cf5-7065-4c93-959d-a333ab855aa5",
  "request" : {
    "urlPath" : "/fetch-recommendations",
    "method" : "PUT",
    "headers" : {
      "Content-Type" : {
        "equalTo" : "application/json"
      }
    },
    "bodyPatterns" : [ {
      "matchesJsonPath" : "$[?(@.['userId'] =~ /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/)]"
    }, {
      "matchesJsonPath" : "$.['preferredGenres'][?(@ == 'Platformer')]"
    }, {
      "matchesJsonPath" : "$.['preferredGenres'][?(@ == 'Stealth')]"
    }, {
      "matchesJsonPath" : "$.['preferredGenres'][?(@ == 'Adventure')]"
    } ]
  },
  "response" : {
    "status" : 200,
    "body" : "{\"videogames\":[{\"name\":\"Red Dead Redemption\",\"genre\":\"Adventure\"},{\"name\":\"Crash Bandicoot 3\",\"genre\":\"Platformer\"}]}",
    "headers" : {
      "Content-Type" : "application/json"
    },
    "transformers" : [ "response-template", "spring-cloud-contract" ]
  },
  "uuid" : "49330cf5-7065-4c93-959d-a333ab855aa5",
  "priority" : 2
}

In conclusion, how the matching criteria for mappings in WireMock works?

1

There are 1 best solutions below

0
Edgar Hernandez On

WireMock doesn't pick the mapping with exact matches. In my case both mappings match (yes one more than other) from the mapping perspective.

So the decisive point here is the order in which the mappings are loaded, the one that is encounter first in the list of matched mappings is picked.

For a better explanation and example, check this answer: https://stackoverflow.com/a/62381321/8600439