WireMock – 如何将请求的 JSON 主体包含到响应主体中?

huangapple go评论68阅读模式
英文:

WireMock - How to Include Request JSON Body Into the Response Body?

问题

我迄今为止取得了什么成就?

我正在使用 WireMock 与 Spring Boot 应用程序以及 JUNIT 5 进行测试。

我正在为 test 端点设置自定义的请求和响应 JSON 负载:

请求负载:

{
    "merchantId": "xxxx",
    "data": [
        {
            "id": "unique-id-1",
            "sensitiveData": "xxxxxx"
        },
        // 其他数据...
    ]
}

响应负载:

{
    "status": "SUCCESS",
    "tokens": [
        {
            "id": "unique-id-1",
            "token": "xxxxxxxxxx"
        },
        // 其他数据...
    ]
}

我想要实现什么?

由于我的 JSON 请求负载是动态的,我希望在响应中也创建一个动态的 JSON 负载,其中 JSON 中的令牌值是静态的,但 JSON 中的 id 值是基于请求负载的 id 值的动态值。

@SpringBatchTest
class FileTest {
    private WireMockServer wireMockServer;

    @BeforeEach
    void setUp() {
        wireMockServer =
                new WireMockServer(options().extensions(new ResponseTemplateTransformer(true)).port(PORT));

        WireMock.configureFor("localhost", PORT);
        wireMockServer.start();
    }

    @AfterEach
    void tearDown() {
        wireMockServer.stop();
    }

    @Test
    void testEndToEndFlowForSpringBatch() {
        final String body = ResponsePayload.getResponseJsonPayload();
        wireMockServer.addStubMapping(
                stubFor(
                        post(urlPathMatching("/test"))
                                .willReturn(
                                        aResponse()
                                                .withBody(body)
                                                .withStatus(200)
                                                .withTransformers("response-template"))));
        // 更多代码
    }
}
ResponsePayload.getResponseJsonPayload() 包含以下值:
{
    "response": "SUCCESS",
    "tokens": [
        {
            "id": "{{jsonPath request.body '$.data[0].id'}}",
            "token": "xxxxxx"
        },
        {
            "id": "{{jsonPath request.body '$.data[1].id'}}",
            "token": "xxxxxxx"
        },
        // 其他数据...
    ]
}

什么不起作用?

当我调试程序时,我可以看到存根正在引发以下错误:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 500 </title>
</head>
<body>
<h2>HTTP ERROR: 500</h2>
<p>Problem accessing /test. Reason:
<pre>    wiremock.com.github.jknack.handlebars.HandlebarsException: inline@1e0c0274:5:21: could not find helper: 'jsonPath'
            "id": "{{jsonPath request.body '$.merchantId'}}",
                     ^
</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>

我已经阅读了以下答案,但找不到如何使用 jsonPath 的方法:

任何帮助将不胜感激。

谢谢!

英文:

<h2>What I have achieved so far?</h2>

I'm using WireMock with Spring Boot Application using the JUNIT 5.

I am stubbing the test endpoint with the custom Request and Response JSON payload:

REQUEST PAYLOAD:

{
    &quot;merchantId&quot;: &quot;xxxx&quot;,
    &quot;data&quot;: [
        {
            &quot;id&quot;: &quot;unique-id-1&quot;,
            &quot;sensitiveData&quot;: &quot;xxxxxx&quot;,
        },
      ...
      ...
   ]
}

RESPONSE PAYLOAD:

{
    &quot;status&quot;: &quot;SUCCESS&quot;,
    &quot;tokens&quot;: [
        {
            &quot;id&quot;: &quot;unique-id-1&quot;,
            &quot;token&quot;: &quot;xxxxxxxxxx&quot;,
        },
           ...
           ...  

   ]
}

<h2>What I'm trying to achieve?</h2>
Since my JSON Request payload is dynamic. I want to create a dynamic JSON Payload in response as well where tokens values in JSON are static but the id's value in JSON is dynamic based on the request payload's id value.

@SpringBatchTest
class FileTest{
   private WireMockServer wireMockServer;

   BeforeEach
   void setUp() {
       wireMockServer =
         new WireMockServer(options().extensions(new          
             ResponseTemplateTransformer(true)).port(PORT));

       WireMock.configureFor(&quot;localhost&quot;, PORT);
       wireMockServer.start();
  }

  @AfterEach
  void tearDown() {
       wireMockServer.stop();
  

@Test
  void testEndToEndFlowForSpringBatch() {
       final String body = ResponsePayload.getResponseJsonPayload();
       wireMockServer.addStubMapping(
        stubFor(
            post(urlPathMatching(&quot;/test&quot;))
                .willReturn(
                    aResponse()
                        .withBody(body)
                        .withStatus(200)
                        .withTransformers(&quot;response-template&quot;))));
       //morecode
}

<h6>ResponsePayload.getResponseJsonPayload() contains below value:</h6>

{
    &quot;response&quot;: &quot;SUCCESS&quot;,
    &quot;tokens&quot;: [
        {
            &quot;id&quot;: &quot;{{jsonPath request.body &#39;$.data[0].id&#39;}}&quot;,
            &quot;token&quot;: &quot;xxxxxx&quot;,
        },
        {
            &quot;id&quot;: &quot;{{jsonPath request.body &#39;$.data[1].id&#39;}}&quot;,
            &quot;token&quot;: &quot;xxxxxxx&quot;,
        },
                  ..
    ]
}

<h2>What is not working?</h2>
When I am debugging the program I can see the stub is throwing following error:

&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;charset=ISO-8859-1&quot;/&gt;
&lt;title&gt;Error 500 &lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h2&gt;HTTP ERROR: 500&lt;/h2&gt;
&lt;p&gt;Problem accessing /test. Reason:
&lt;pre&gt;    wiremock.com.github.jknack.handlebars.HandlebarsException: inline@1e0c0274:5:21: could not find helper: &amp;apos;jsonPath&amp;apos;
            &amp;quot;id&amp;quot;: &amp;quot;{{jsonPath request.body &amp;apos;$.merchantId&amp;apos;}}&amp;quot;,
                     ^
&lt;/pre&gt;&lt;/p&gt;
&lt;hr /&gt;&lt;i&gt;&lt;small&gt;Powered by Jetty://&lt;/small&gt;&lt;/i&gt;
&lt;/body&gt;
&lt;/html&gt;

I've already read below answers but couldn't find a way of using the jsonPath:

Any help would be appreciable.

Thanks!

答案1

得分: 1

我只需要升级WireMock的版本,以解决问题。将版本从&lt;version&gt;2.6.0&lt;/version&gt;升级到最新版本&lt;version&gt;3.0.0-beta-9&lt;/version&gt;

依赖项:

&lt;dependency&gt;
    &lt;groupId&gt;com.github.tomakehurst&lt;/groupId&gt;
    &lt;artifactId&gt;wiremock-standalone&lt;/artifactId&gt;
    &lt;version&gt;3.0.0-beta-9&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;

你可以在Maven存储库中获取最新版本:Maven Store

另外,可以这样创建服务器:

private WireMockServer wireMockServer;

@BeforeEach
void setUp() {
    wireMockServer =
        new WireMockServer(
                options()
                .extensions(new ResponseTemplateTransformer(true))
                .port(PORT));

    wireMockServer.start();
}

在存根中:

@Test
void testWireMockServerIsUp() {
    wireMockServer.stubFor(
        post(urlPathMatching("/test"))
            .willReturn(
                aResponse().withBody(body).withStatus(200)));
}
英文:

All I needed to fix the issue was to upgrade the version of WireMock from &lt;version&gt;2.6.0&lt;/version&gt; to the latest one &lt;version&gt;3.0.0-beta-9&lt;/version&gt;.

Dependency:

&lt;dependency&gt;
    &lt;groupId&gt;com.github.tomakehurst&lt;/groupId&gt;
    &lt;artifactId&gt;wiremock-standalone&lt;/artifactId&gt;
    &lt;version&gt;3.0.0-beta-9&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;

You can get the latest one from the Maven store here: Maven Store

Also, create the server this way:

private WireMockServer wireMockServer;

@BeforeEach
void setUp() {
    wireMockServer =
        new WireMockServer(
                options()
                .extensions(new ResponseTemplateTransformer(true))
                .port(PORT));

    wireMockServer.start();
}

And in the stub:

@Test
void testWireMockServerIsUp() {
    wireMockServer.stubFor(
        post(urlPathMatching(&quot;/test&quot;))
            .willReturn(
                aResponse().withBody(body).withStatus(200)));
}

huangapple
  • 本文由 发表于 2023年6月12日 18:17:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455655.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定