Search code examples
javapact

Why do we need unit test in a PACT test?


Recently, I have familiarised myself with PACT testing. Really cool idea to stub out producer/consumer for each counter party. However, I do not understand one core principle. On the client PACT test, the one that generates the PACT json file - why do I need to spin up a test server and hit that with specific requests?

E.g. I have Producer called A, and I have consumer B. Producer A has endpoint getAllUsers, which will return json of all users. In consumer B, I have written pact test:

@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "ProducerA", port = "1234")
public class ProducerAPactTest {

    private static JSONArray body = new JSONArray("[ {'user_id': '1' }]");

    @Pact(provider = "ProducerA", consumer = "ConsumerB")
    RequestResponsePact createPact(PactDslWithProvider builder) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", ContentType.APPLICATION_JSON.toString());

        DslPart regionDsl = PactDslJsonArray.arrayEachLike()
            .stringType("id", "1").closeObject().closeArray();

        return builder.given("Normal state")
            .uponReceiving("Get all users request")
            .path("/users").method("GET").willRespondWith()
            .status(200).headers(headers).body(regionDsl).toPact();
    }

    @Test
    void runTest() {
        // when
        ResponseEntity<String> response = new RestTemplate()
            .getForEntity(mockServer.getUrl() + "/users", String.class);
        // then
        assertThat(response.getStatusCode().value()).isEqualTo(200);
        List<String> contentTypeHeaders = response.getHeaders().get("Content-Type");
        String responseBody = response.getBody();
        assertThat(contentTypeHeaders).isNotNull();
        assertThat(responseBody).isNotNull();
        assertThat(contentTypeHeaders.get(0)).isEqualTo(ContentType.APPLICATION_JSON.toString());
        JSONAssert.assertEquals(responseBody, body, JSONCompareMode.LENIENT);
    }

I have used several tutorials to write the pact test. I am developing under Java, but my question stands in general for all Pact tests. Why do I need to create a unit test? Seems utterly pointless to me to be asserting what I receive, since I've defined that myself just few lines above? I've noticed that all pact consumer tests follow the same pattern. What am I missing?


Solution

  • Typically, the class under test would do more than just deserialize the JSON body. Sorry that this is a Ruby example and not a java one, but here's an example of a client class that turns the JSON document into a model that represents the resource: https://github.com/pact-foundation/pact-ruby/blob/master/example/zoo-app/lib/zoo_app/animal_service_client.rb

    We use a pact test here to check how it behaves with different http responses (eg. it converts a 404 into a null). If you're just testing your HTTP response directly, then you're not getting much value for your consumer code at all, apart from setting up a contract with the provider.