Eugene A
Eugene A

Reputation: 330

Wiremock variable substitution in JSON response

I am trying to configure Wiremock mappings to return a JSON response with a value from the request.

The request is simply

{ "clientTag": "123" }

And the mapping for it is:

{
  "priority": 4,
  "request": {
    "method": "POST",
    "urlPattern": "/test"
  },
  "response": {
    "status": 200,
    "body": "{ \"loginId\": \"${loginId}\" }",
    "headers": {
      "Content-Type": "application/json"
    }
  },
  "captures" : [ {
            "source" : "BODY",
            "target" : "loginId",
            "pattern" : "$..clientTag",
            "captureGroup" : 1
  } ]
}

I receive the response:

{ "loginId": "" }

while the expected one is:

{ "loginId": "123" }

If I switch to XML requests, everything works fine with the pattern <clientTag>(.*?)</clientTag>, but I would like to stick to JSON.

Unfortunately Wiremock documentation is scarce hence the question. Any ideas?

UPDATE: If someone is reading this later, you'd do best to use the transforms in the code, which are available in the later Wiremock versions.

Upvotes: 4

Views: 9514

Answers (3)

Mark Han
Mark Han

Reputation: 3145

This seems like a perfect use-case for OpenTable's Wiremock Body Transformer.

It can be easily integrated with the Standalone Server like this:

java -cp "wiremock-body-transformer-1.1.6.jar:wiremock-2.3.1-standalone.jar" com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --verbose --extensions com.opentable.extension.BodyTransformer

This extension allows you to easily specify a variable in the request that you would want to match in the response.

{
    "request": {
        "method": "POST",
        "urlPath": "/transform",
        "bodyPatterns": [
            {
                "matchesJsonPath": "$.name"
            }
        ]
    },
    "response": {
        "status": 200,
        "body": "{\"responseName\": \"$(name)\"}",
        "headers": {
            "Content-Type": "application/json"
        },
        "transformers": ["body-transformer"]
    }
}

It also easily allows you to generate a random integer in the response as seen here:

{
    "request": {
        "method": "POST",
        "urlPath": "/transform",
    },
    "response": {
        "status": 200,
        "body": "{\"randomInteger\": \"$(!RandomInteger)\"}",
        "headers": {
            "Content-Type": "application/json"
        },
        "transformers": ["body-transformer"]
    }
}

Upvotes: 2

Stef Heyenrath
Stef Heyenrath

Reputation: 9830

WireMock.Net does support this now.

When sending a request like:

{
    "username": "stef"
}

And using mapping like:

{
  "Request": {
    "Path": {
      "Matchers": [
        {
          "Name": "WildcardMatcher",
          "Pattern": "/test"
        }
      ]
    },
    "Methods": [
      "post"
    ]
  },
  "Response": {
    "StatusCode": 200,
    "BodyAsJson": {
      "path": "{{request.path}}",
      "result": "{{JsonPath.SelectToken request.bodyAsJson \"username\"}}"
    },
    "UseTransformer": true,
    "Headers": {
      "Content-Type": "application/json"
    }
  }
}

The response will be like:

{
    "path": "/test",
    "result": "stef"
}

Note that this functionality is currently in preview mode, see NuGet package version 1.0.4.8-preview-01.

If you have any questions, just create an issue on this github project.

Upvotes: 3

Tom
Tom

Reputation: 4149

Unless you've added an extension you haven't mentioned, this can't work - there's no "captures" element in the JSON API, and no way (without extensions) to do variable substitution in responses.

Upvotes: 1

Related Questions