Hi Ronald,
Thanks for your answer.
Just starting to play with Pact and I still struggle to create a good picture how should I use the stateChangeUrl from the pact-jvm maven plugin.
- URL to use to switch the state of the provider
- This URL will receive the providerState description from the pact file before each interaction via a POST.
I created a new state in consumer tests: @Pact(state = "book a car with setup", provider = "Provider", consumer = "Consumer").
what will be my stateChangeUrl?
is it one of the mocked URL? or, as you mentioned it's an endpoint which loads test data for you?
How to define and pass the state description?
Also a question:
There is any way to parameterize the json pact file, and to inject some variables? For example in my case I need to inject the IDs of the documents created in dependent services during the setUp.
My consumer test:
class ServiceConsumerTest {
def DATA_A_ID = "AAAAAAAA_ID";
def DATA_B_ID = "BBBBBBBB_ID";
def headers = ["Content-Type" : "application/json;charset=UTF-8"]
@Rule
public PactRule rule = new PactRule("localhost", 1234, this);
@Pact(state = "book a car", provider = "Provider", consumer = "Consumer")
public PactFragment configurationFragment(ConsumerPactBuilder.PactDslWithProvider.PactDslWithState builder) {
return builder
.uponReceiving("retrieve data from Service-A")
.path("/persons/${DATA_A_ID}")
.method("GET")
.willRespondWith()
.headers(headers)
.status(200)
.body("{\t\n" +
"\t\"firstName\":\"John\",\n" +
"\t\"lastName\":\"Smith\"\n" +
"}")
.uponReceiving("retrieving data from Service-B")
.path("/cars/${DATA_B_ID}")
.method("GET")
.willRespondWith()
.headers(headers)
.status(200)
.body("{\t\n" +
"\t\"brand\":\"Honda\",\n" +
"\t\"model\":\"Civic\",\n" +
"\t\"year\": 2012\n" +
"}")
.uponReceiving("book a car")
.path("/orders/")
.method("POST")
.body("{\n" +
"\tperson: {\n" +
"\t\"id\" : \"AAAAAA_ID\",\t\t\n" +
"\t\"firstName\":\"John\",\n" +
"\t\"lastName\":\"Smith\"\n" +
"\t}\n" +
"\n" +
"\tcar:\t{\n" +
"\t\"id\":\"BBBBBB_ID\"\t\n" +
"\t\"brand\":\"Honda\",\n" +
"\t\"model\":\"Civic\",\n" +
"\t\"year\": 2012\n" +
"\t}\n" +
"}")
.willRespondWith()
.headers(headers)
.status(201)
.body("{\n" +
"\t\"id\": \"ORDER_ID_XXXXX\"\n" +
"}")
.toFragment();
}
@Pact(state = "book a car with setup", provider = "Provider", consumer = "Consumer")
public PactFragment configurationFragment(ConsumerPactBuilder.PactDslWithProvider.PactDslWithState builder) {
//TODO SETU_UP ????
// Create person and person_ID
// Create cart and get car_ID
return builder
.uponReceiving("retrieve data from Service-A")
.path("/persons/${DATA_A_ID}")
.method("GET")
.willRespondWith()
.headers(headers)
.status(200)
.body("{\t\n" +
"\t\"firstName\":\"John\",\n" +
"\t\"lastName\":\"Smith\"\n" +
"}")
.uponReceiving("retrieving data from Service-B")
.path("/cars/${DATA_B_ID}")
.method("GET")
.willRespondWith()
.headers(headers)
.status(200)
.body("{\t\n" +
"\t\"brand\":\"Honda\",\n" +
"\t\"model\":\"Civic\",\n" +
"\t\"year\": 2012\n" +
"}")
.uponReceiving("book a car")
.path("/orders/")
.method("POST")
.body("{\n" +
"\tperson: {\n" +
"\t\"id\" : \"AAAAAA_ID\",\t\t\n" +
"\t\"firstName\":\"John\",\n" +
"\t\"lastName\":\"Smith\"\n" +
"\t}\n" +
"\n" +
"\tcar:\t{\n" +
"\t\"id\":\"BBBBBB_ID\"\t\n" +
"\t\"brand\":\"Honda\",\n" +
"\t\"model\":\"Civic\",\n" +
"\t\"year\": 2012\n" +
"\t}\n" +
"}")
.willRespondWith()
.headers(headers)
.status(201)
.body("{\n" +
"\t\"id\": \"ORDER_ID_XXXXX\"\n" +
"}")
.toFragment();
}
@PactVerification("book a car")
@Test
void "testBookCar"()
{
Assert.assertEquals(200, response.getStatusCode());
Assert.assertNotNull(response.get("orderId"));
}
}
Part of my pom file:
<plugin>
<groupId>au.com.dius</groupId>
<artifactId>pact-jvm-provider-maven_2.11</artifactId>
<version>2.1.9</version>
<configuration>
<serviceProviders>
<!-- You can define as many as you need, but each must have a unique name -->
<serviceProvider>
<name>checkout-provider</name>
<!-- All the provider properties are optional, and have sensible defaults (shown below) -->
<stateChangeUrl>
?????
</stateChangeUrl>
<protocol>http</protocol>
<host>localhost</host>
<port>8080</port>
<!--<path>/</path>-->
<requestFilter>
<!--request.addHeader-->
</requestFilter>
<consumers>
<!-- Again, you can define as many consumers for each provider as you need, but each must have a unique name -->
<consumer>
<name>checkout-consumer</name>
<!-- currently supports a file path using pactFile or a URL using pactUrl -->
<pactFile>${project.basedir}/pacts/Consumer-Provider.json</pactFile>
</consumer>
</consumers>
</serviceProvider>
</serviceProviders>
<configuration>
<pact.showStacktrace>true</pact.showStacktrace>
</configuration>
</configuration>
</plugin>
Thanks a lot in advance,
Alex
PS: if you have an example it'll be awesome!
PSS: Let me know if on the right track, any feedback is welcome:)