Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use WireMock's response template in JUnit 5 Tests

Tags:

java

wiremock

I'm trying to use the Response Templating feature of WireMock, but it does not seem to work with the sample piece of code provided in the docs.

This is a sample piece of code:


import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import io.restassured.RestAssured;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class WireMockTest {

  @Rule
  public WireMockRule wm = new WireMockRule(options()
      .extensions(new ResponseTemplateTransformer(true)));
  private WireMockServer wireMockServer;

  @BeforeEach
  public void setup() {
    this.wireMockServer = new WireMockServer(
        options().port(8081));
    this.wireMockServer.stubFor(get(urlEqualTo("/test-url"))
        .willReturn(aResponse()
            .withBody("{{request.url}}")
            .withTransformers("response-template")));
    this.wireMockServer.start();
  }

  @Test
  public void test() {
    RestAssured.when()
        .get("http://localhost:8081/test-url")
        .then()
        .log().ifError()
        .body(Matchers.equalTo("/test-url"));
  }

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

Expected Output:

Tests should pass. (meaning the {{request.url}} should be substituted with /test-url as a result of template rendering).

Actual Output:

....

java.lang.AssertionError: 1 expectation failed.
Response body doesn't match expectation.
Expected: "/test-url"
  Actual: {{request.url}}

Things I've tried:

  1. Since these are test cases using JUnit 5 API, did not add @Rule WireMockRule, instead added the .withTransformers("response-template").
  2. Tried changing the test cases to use JUnit 4 API, and added
@Rule
public WireMockRule wm = new WireMockRule(options()
    .extensions(new ResponseTemplateTransformer(false))
);

(along with withTransformers)
3. Changed the WireMockRule to

@Rule
public WireMockRule wm = new WireMockRule(options()
    .extensions(new ResponseTemplateTransformer(true))
);

(along with withTransformers)
4. Removed the withTransformers only keeping the WireMockRule. (JUnit 4)
5. I've also tried the above combination with JUnit 5 API too.

But none of the above variations worked. Is there anything that I'm missing?

like image 717
Kenpachi Avatar asked Mar 09 '20 07:03

Kenpachi


1 Answers

The @Rule approach won't work because you are ignoring the WireMockServer created/managed by te rule as you are creating a new one yourself in the @BeforeEach.

You should remove the rule and add the ResponseTemplateTransformer in your @BeforeEach to the WireMockServer through the Options object.

Something like this should do the trick (judging from the Javadoc).

@BeforeEach
  public void setup() {
    this.wireMockServer = new WireMockServer(
        options()
          .extensions(new ResponseTemplateTransformer(false))
          .port(8081));
    this.wireMockServer.stubFor(get(urlEqualTo("/test-url"))
        .willReturn(aResponse()
            .withBody("{{request.url}}")
            .withTransformers("response-template")));
    this.wireMockServer.start();
  }
like image 178
M. Deinum Avatar answered Sep 28 '22 08:09

M. Deinum