familon16 / jsif

Self Initializing Fake library for the JVM (inspired by https://martinfowler.com/bliki/SelfInitializingFake.html)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status

jsif

Self Initializing Fake library for the JVM (inspired by https://martinfowler.com/bliki/SelfInitializingFake.html)

What does it do?

It creates a self initialized fake based on a communication with a real server.
On the first time that you run it, it runs in a Recording mode, means that it proxies the communication to a real server and at the same time saves the communication in to a file.
On consecutive runs it'll start up in a Playback mode, means that it loads the data from the recorded run and behaves like the real server.

Let's see a real life example, we have this very basic Weather class that communicates with an external Weather service (https://www.metaweather.com/). This class should have Integration Test to make sure that it functions correctly.

Weather.java

package com.maxondev.sample.app;

import org.apache.http.client.fluent.Request;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class Weather {

    private final String baseUrl;

    public Weather(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String forCity(String city) throws IOException {
        String encodedCity = URLEncoder.encode(city, StandardCharsets.UTF_8.name());
        return Request
                .Get(baseUrl + "/api/location/search/?query=" + encodedCity)
                .execute()
                .returnContent()
                .asString();
    }
}

That's how the test will look With jsif (Java SelfInitializingFake)

WeatherIT.java

package com.maxondev.sample.app;

import com.maxondev.jsif.SelfInitializedFake;
import org.hamcrest.CoreMatchers;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.IOException;

public class WeatherIT {
    private static final int fakePort = 8087;
    private static final SelfInitializedFake fake =
            SelfInitializedFake
                    .builder()
                    .proxyTo("https://www.metaweather.com")
                    .recordTo("weather_recordings")
                    .listenOnPort(fakePort)
                    .asAutoMode();

    @BeforeClass
    public static void setUpBeforeClass() {
        fake.start();
    }

    @AfterClass
    public static void tearDownAfterClass() {
        fake.stop();
    }

    @Test
    public void forCity_success() throws IOException {
        Weather weather = new Weather("http://localhost:" + fakePort);

        String res = weather.forCity("london");

        Assert.assertThat(res, CoreMatchers.containsString("\"latt_long\":\"51.506321,-0.12714\""));
    }

    @Test
    public void forCity_wrongCity_emptyResult() throws IOException {
        Weather weather = new Weather("http://localhost:" + fakePort);

        String res = weather.forCity("london");

        Assert.assertThat(res, CoreMatchers.containsString("\"latt_long\":\"51.506321,-0.12714\""));
    }
}

How does it work?

When running for the first time, you'll see in the log
[main] INFO com.maxondev.jsif.SelfInitializedFake - Starting in `Record` mode
And the Fake will initialize itself - It'll proxy the communication to the real external server and record it. The communication will be persisted in into a json file (under test/resources/weather_recordings)

The next time that you'll run it, you'll see in the log
[main] INFO com.maxondev.jsif.SelfInitializedFake - Starting in `Play` mode
The Fake will run in Play mode now and it'll interact in the same way, but this time instead of proxying the traffic to the real server it'll use the persisted communication from the first run.

Under the hood?

This library uses WireMock library (http://wiremock.org/) for the recording & playback.
It wraps WireMock and allows an easy Self Initializing Fake.

About

Self Initializing Fake library for the JVM (inspired by https://martinfowler.com/bliki/SelfInitializingFake.html)

License:Apache License 2.0


Languages

Language:Java 100.0%