Pact. How to test a REST GET with automatically generated ID in the URL

1.5k views Asked by At

I want to test a REST service that returns the detail of a given entity identified by an UUID, i.e. my consumer pact has an interaction requesting a GET like this:

/cities/123e4567-e89b-12d3-a456-426655440000

So I need this specific record to exist in the Database for the pact verifier to find it. In other projects I've achieved this executing an SQL INSERT in the state setup, but in this case I'd prefer to use the microservice's JPA utilities for accessing to the DB, because the data model is quite complex and using these utilities would save me much effort and make the test much more maintainable.

The problem is that these utilities do not allow specifying the identifier when you create a new record (they assign an automatic ID). So after creating the entity (in the state setup) I'd like to tell the pact verifier to use the generated ID rather than the one specified by the consumer pact.

As far as I know, Pact matching techniques are not useful here because I need the microservice to receive this specific ID. Is there any way for the verifier to be aware of the correct ID to use in the call to the service?

3

There are 3 answers

1
Ronald Holshausen On BEST ANSWER

You have two options here:

Option 1 - Find a way to use the UUID from the pact file

This option (in my option) would be the better one, because you are using well known values for you verification. With JPA, I think you may be able to disable the auto-generation of the ID. And if you are using Hibernate as the JPA provider, it may not generate an ID if you have provided it one (i.e. setting the ID on the entity to the one from the pact file before saving it). This is what I have done recently.

Using a generator (as mentioned by Beth) would be a good mechanism for this problem, but there is no current way to provide a generator to use a specific value. They generate random ones on the fly.

Option 2 - Replace the ID in the URL

Depending on how you run the verification, you could use a request filter to change the UUID in the URL to the one which was created during the provider state callback. However, I feel this is a potentially bad thing to do, because you could change the request in a way that weakens the contract. You will not be verifying that your provider adheres to what the consumer specified.

If you choose this option, be careful to only change the UUID portion of the URL and nothing else.

For information on request filters, have a look at Gradle - Modifying the requests before they are sent and JUnit - Modifying the requests before they are sent in the Pact-JVM readmes.

1
Beth Skurrie On

If you are using pact-jvm on both the consumer and provider sides, I believe you may be able to use 'generators', but you'll need to look up the documentation on that as I haven't used them.

0
Matthew Fellows On

Unfortunately not. The provider side verifier takes this information from the pact file itself and so can't know how to send anything else.

The best option is to use provider states to manage the injection of the specific record prior this test case (or to just have the correct record in there in the first place).

You use the JPA libraries during the provider state setup to modify the UUID in record to what you're expecting.