I'm writing a suite of microservices using Spring Boot, and I need to run some BDD-style integration tests that test each one independent of the other. In order to figure out how, I have written a very simple contract using Spring Cloud Contract on one of the producers. Here it is:
org.springframework.cloud.contract.spec.Contract.make {
description("Contract for the command endpoint where a consumer can send the service individual commands")
name("CommandEndpoint")
request {
method 'POST'
urlPath('/myendpoint')
headers {
contentType(applicationJson())
}
body(["rootId" : "1234", "reportId" : "7ea6bfba-ec22-4a53-b6e9-9261ee459b69"])
}
response {
status OK()
}
}
On the consumer side, I've gotten a stub running just fine. I'm using Cucumber in my integration tests, so I've setup the runner like so:
@RunWith(Cucumber.class)
@CucumberOptions(features= {"src/test/resources/features"},
glue = {"bdd/stepDefinitions"},
dryRun = false)
public class CucumberRunnerIT {
}
And I'm setting up the Spring application context like this:
@SpringBootTest(webEnvironment=WebEnvironment.NONE, classes = { BddConfig.class })
@AutoConfigureStubRunner(ids = {"com.blah.consumer:my-consumer:0.0.48:stubs:6565"},
stubsMode = StubRunnerProperties.StubsMode.LOCAL)
public class SpringContextLoader {
private static final Logger LOGGER = LogManager.getLogger(SpringContextLoader.class);
@Before
public void setUp() {
LOGGER.info("LOADING SPRING CONTEXT");
}
}
When I point my consumer to http://localhost:6565 it sends the request just fine - I can see the stub receive it in the console output. However, what I want to do now is something akin to a WireMock.verify() operation. I want my integration test to verify that the stub received a request on the correct endpoint with the correct request body. However, when I attempt to simply do:
verify(postRequestedFor(urlEqualTo("/myendpoint")));
I get this error after a rather lengthy delay:
com.github.tomakehurst.wiremock.common.JsonException: {
"errors" : [ {
"code" : 10,
"source" : {
"pointer" : "/timestamp"
},
"title" : "Error parsing JSON",
"detail" : "Unrecognized field \"timestamp\" (class com.github.tomakehurst.wiremock.common.Errors), not marked as ignorable"
} ]
}
at com.github.tomakehurst.wiremock.common.JsonException.fromJackson(JsonException.java:49)
at com.github.tomakehurst.wiremock.common.Json.read(Json.java:52)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.safelyExecuteRequest(HttpAdminClient.java:449)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.postJsonAssertOkAndReturnBody(HttpAdminClient.java:383)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.countRequestsMatching(HttpAdminClient.java:222)
at com.github.tomakehurst.wiremock.client.WireMock.verifyThat(WireMock.java:526)
at com.github.tomakehurst.wiremock.client.WireMock.verifyThat(WireMock.java:511)
at com.github.tomakehurst.wiremock.client.WireMock.verify(WireMock.java:549)
at bdd.stepDefinitions.VerificationToIrsSteps.i_validate_the_outcomes(VerificationToIrsSteps.java:33)
at ✽.I validate the outcomes(src/test/resources/features/VerificationToIrs.feature:25)
I imagine there's some more setup I need to do in order to use WireMock in conjunction with Spring Cloud Contract, but I'm not certain how to do it. I've attempted to find some info in the docs, but I'm admittedly lost. I'd really appreciate any help!
Interesting...
What you can try to do if you're using dynamic ports, is to retrieve the URI to the given stub either via @StubRunnerPort("myConsumer") int stubPort
or Stub Runner Rule or Extension and then call new WireMock("localhost", stubPort).verifyThat(...)
.
Since you have a static port 6565, you're saying that doing `new WireMock("localhost", 6565).verifyThat(...) doesn't work for you?
You can check for an example here https://github.com/spring-cloud/spring-cloud-contract/issues/457