How to get started on Pact in Java

If you heard about contract testing, but just like me you didn’t know where to start, you could benefit from a simple and self-contained tutorial. It is a good idea to start with Pact 101 so you have some ideas about what it does. Also check pact-jvm-consumer-junit out for more explanation if needed.

Let ‘s assume your application relies on an external user service. In order to make sure your changes doesn’t break the API contract you are going to write a Pact consumer test for it (user service being the provider here).

public class UserServiceClient {
    private final String endpoint;

    public UserServiceClient(String endpoint) {
        this.endpoint = endpoint;
    }

    public User getUser(long userId) {
        String url = endpoint + "/users/" + userId;
        Client client = ClientBuilder.newClient();
        return client.target(url).request(MediaType.APPLICATION_JSON_TYPE).get(User.class);
    }
}

All you need to do is to instruct JUnit to identify the tests that require Pact verification, spawn a mock server and use the fragments you have created that describe the interaction between a provider and a consumer. Feel free to clone the complete working code from https://github.com/n0rm1e/simple-java-pact-test and run it for yourself.

public class UserServiceClientTest {
    private final int testUserId = 1;
    private final User testUser = new User("Bob", "Smith");

    @Rule
    // Wrap all the tests with PactVerification annotation
    public PactProviderRule provider = new PactProviderRule("my-provider-name", "localhost", 8080, this);

    @Test
    // Set up a mock server for the test
    @PactVerification (fragment = "getUserFragment")
    public void shouldGetUsers() {
        UserServiceClient client = new UserServiceClient("http://localhost:8080");
        User user = client.getUser(testUserId);
        assertThat(user, is(testUser));
    }

    // Describe the interaction between a provider and a consumer
    @Pact (consumer = "my-consumer-name", provider = "my-provider-name")
    public PactFragment getUserFragment(PactDslWithProvider builder) throws JsonProcessingException {
        Map<String, String> responseHeaders = new HashMap<>();
        responseHeaders.put("Content-Type", "application/json");

        ObjectMapper objectMapper = new ObjectMapper();
        String testUserJsonString = objectMapper.writeValueAsString(testUser);

        return builder
                .uponReceiving("A request for user " + testUserId)
                .path("/users/" + testUserId)
                .method("GET")
                .willRespondWith()
                .status(200)
                .headers(responseHeaders)
                .body(testUserJsonString)
                .toFragment();
    }
}

The next step is to have a broker manage the contract between the provider and consumer, which is the topic for another post.

Advertisements

Leave a Reply

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

WordPress.com Logo

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

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s