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

Tags: ,



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?

Answer

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();
  }


Source: stackoverflow