Adding a stub

In the last post, Extending and refactoring Yatspect suite we found several problems with the initial implementation of the tests. Two of them where:

  1. We are running our acceptance test against a real prod server. This is a luxury we can’t always afford.
    • Sometimes we need to go to third party APIs with invocations that would mutate their state. That would mutate production for testing purposes.
    • We would like to record the interactions between our app and the Star Wars API.
  2. The acceptance test is veeeeery slow. It takes several seconds to execute, whereas the helloWorld test takes around half a second. This is probably related with point (1).

We are going to add a Wiremock stub to pretend to be the real thing during testing.

Adding wiremock to the pom.xml:

        <!-- Wiremock, used to mock over the wire communications -->

Wiremock will force us to use it’s version of jetty, so you will probably want to change your jetty version to match it:


Now we have to make sure that a Wiremock instance is running whenever we run an acceptance test.

public abstract class AbstractAcceptanceTest extends TestState implements WithCustomResultListeners {

    private static final int WIREMOCK_PORT = 8888;
    private ExampleApp exampleApp = new ExampleApp();
    private WireMockServer wireMockServer;

    public void setUp() throws Exception {;

    public void tearDown() throws Exception {
        capturedInputAndOutputs.add("Sequence Diagram", generateSequenceDiagram());

    private void startWiremock() {
        wireMockServer = new WireMockServer(WIREMOCK_PORT);

    private void primeDefaultWiremockMessage() {
        new WireMock(WIREMOCK_PORT).register(WireMock.any(new UrlPattern(new AnythingPattern(), true)).willReturn(new ResponseDefinitionBuilder().withBody("These are not the droids you're looking for").withStatus(666)));


Note that apart from starting up Wiremock we are also providing a default priming that will be hit whenever no other priming is found. If you don’t do that, wiremock will return a 404 by default. Returning a weird code (666) when something goes wrong is useful to distinguish accidental 404 codes from intentional ones. Imagine that you are trying to test a sad path where you actually expect a 404… if that is also the default priming, you could get a 404 for the wrong reason!

Now we have to prime Wiremock in our test. First we will write the class that knows how to prime wiremock for this use case:

public class Givens {

    public static GivensBuilder theStarWarsServiceKnowsAboutLuke() {
        return interestingGivens -> {
            WireMock wiremock = new WireMock(8888);
                     .withBody("<the body was omitted for brevity>")));
                            .withBody("<the body was omitted for brevity>")));
                            .withBody("<the body was omitted for brevity>")));
            return interestingGivens;

And now we add the priming to the test:

public void shouldTalkAboutLukeSkywalkerByDefault() throws Exception {
    then(theStatusCode(), is(200));
    then(theBody(), is("{\"Description\": \"Luke Skywalker is a Human from Tatooine\"}"));

Now the priming is in place but the production code is still going to This is because we have hardcoded it. In a proper application we would want to have some kind of configuration system. Indeed, we will refactor this app to have it at some point. Nevertheless, for this post our focus is to demonstrate how to hit a Wiremock stub so we are just going to hardcode the stub for now.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    CloseableHttpResponse lukeResponse = getRequestTo("http://localhost:8888/api/people/1/");
    DocumentContext lukeJsonDocument = JsonPath.parse(EntityUtils.toString(lukeResponse.getEntity()));

    String lukeName ="$.name");

    String lukeSpecies = extractName(getRequestTo("$.species[0]")));
    String lukeHomeworld = extractName(getRequestTo("$.homeworld")));

    response.getWriter().print(format("{\"Description\": \"%s is a %s from %s\"}", lukeName, lukeSpecies, lukeHomeworld));



One Comment Add yours

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s