Updated documentation for generating Spring REST Docs snippets (#648)
* Updated documentation with examples how to generate Spring REST Docs snippets from the generated tests. fixes gh-613
This commit is contained in:
committed by
Marcin Grzejszczak
parent
17327462ad
commit
8c5f2f5567
@@ -0,0 +1,31 @@
|
||||
// tag::base_class[]
|
||||
package com.example.fraud;
|
||||
|
||||
import io.restassured.module.mockmvc.RestAssuredMockMvc;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestName;
|
||||
import org.springframework.restdocs.JUnitRestDocumentation;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
||||
|
||||
public abstract class FraudBaseWithStandaloneSetup {
|
||||
|
||||
private static final String OUTPUT = "target/generated-snippets";
|
||||
|
||||
@Rule
|
||||
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(OUTPUT);
|
||||
|
||||
@Rule public TestName testName = new TestName();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
RestAssuredMockMvc.standaloneSetup(MockMvcBuilders.standaloneSetup(new FraudDetectionController())
|
||||
.apply(documentationConfiguration(this.restDocumentation))
|
||||
.alwaysDo(document(getClass().getSimpleName() + "_" + testName.getMethodName())));
|
||||
}
|
||||
|
||||
}
|
||||
// end::base_class[]
|
||||
@@ -0,0 +1,47 @@
|
||||
// tag::base_class[]
|
||||
package com.example.fraud;
|
||||
|
||||
import io.restassured.module.mockmvc.RestAssuredMockMvc;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.restdocs.JUnitRestDocumentation;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class)
|
||||
public abstract class FraudBaseWithWebAppSetup {
|
||||
|
||||
private static final String OUTPUT = "target/generated-snippets";
|
||||
|
||||
@Rule
|
||||
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(OUTPUT);
|
||||
|
||||
@Rule public TestName testName = new TestName();
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
RestAssuredMockMvc.mockMvc(MockMvcBuilders.webAppContextSetup(this.context)
|
||||
.apply(documentationConfiguration(this.restDocumentation))
|
||||
.alwaysDo(document(getClass().getSimpleName() + "_" + testName.getMethodName()))
|
||||
.build());
|
||||
}
|
||||
|
||||
protected void assertThatRejectionReasonIsNull(Object rejectionReason) {
|
||||
assert rejectionReason == null;
|
||||
}
|
||||
}
|
||||
// end::base_class[]
|
||||
@@ -0,0 +1,66 @@
|
||||
package contracts.standalone
|
||||
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request { // (1)
|
||||
method 'PUT' // (2)
|
||||
url '/fraudcheck' // (3)
|
||||
body([ // (4)
|
||||
clientId: $(c(regex('[0-9]{10}')), p("8532032713")),
|
||||
loanAmount: 99999
|
||||
])
|
||||
headers { // (5)
|
||||
contentType('application/vnd.fraud.v1+json')
|
||||
}
|
||||
}
|
||||
response { // (6)
|
||||
status OK() // (7)
|
||||
body([ // (8)
|
||||
fraudCheckStatus: "FRAUD",
|
||||
rejectionReason: "Amount too high"
|
||||
])
|
||||
headers { // (9)
|
||||
contentType('application/vnd.fraud.v1+json')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Since we don't want to force on the user to hardcode values of fields that are dynamic
|
||||
(timestamps, database ids etc.), one can parametrize those entries. If you wrap your field's
|
||||
value in a `$(...)` or `value(...)` and provide a dynamic value of a field then
|
||||
the concrete value will be generated for you. If you want to be really explicit about
|
||||
which side gets which value you can do that by using the `value(consumer(...), producer(...))` notation.
|
||||
That way what's present in the `consumer` section will end up in the produced stub. What's
|
||||
there in the `producer` will end up in the autogenerated test. If you provide only the
|
||||
regular expression side without the concrete value then Spring Cloud Contract will generate one for you.
|
||||
|
||||
From the Consumer perspective, when shooting a request in the integration test:
|
||||
|
||||
(1) - If the consumer sends a request
|
||||
(2) - With the "PUT" method
|
||||
(3) - to the URL "/fraudcheck"
|
||||
(4) - with the JSON body that
|
||||
* has a field `clientId` that matches a regular expression `[0-9]{10}`
|
||||
* has a field `loanAmount` that is equal to `99999`
|
||||
(5) - with header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
(6) - then the response will be sent with
|
||||
(7) - status equal `200`
|
||||
(8) - and JSON body equal to
|
||||
{ "fraudCheckStatus": "FRAUD", "rejectionReason": "Amount too high" }
|
||||
(9) - with header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
|
||||
From the Producer perspective, in the autogenerated producer-side test:
|
||||
|
||||
(1) - A request will be sent to the producer
|
||||
(2) - With the "PUT" method
|
||||
(3) - to the URL "/fraudcheck"
|
||||
(4) - with the JSON body that
|
||||
* has a field `clientId` that will have a generated value that matches a regular expression `[0-9]{10}`
|
||||
* has a field `loanAmount` that is equal to `99999`
|
||||
(5) - with header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
(6) - then the test will assert if the response has been sent with
|
||||
(7) - status equal `200`
|
||||
(8) - and JSON body equal to
|
||||
{ "fraudCheckStatus": "FRAUD", "rejectionReason": "Amount too high" }
|
||||
(9) - with header `Content-Type` matching `application/vnd.fraud.v1+json.*`
|
||||
*/
|
||||
@@ -0,0 +1,29 @@
|
||||
package contracts.webapp
|
||||
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
method 'PUT'
|
||||
url '/fraudcheck'
|
||||
body("""
|
||||
{
|
||||
"clientId":"${value(consumer(regex('[0-9]{10}')), producer('1234567890'))}",
|
||||
"loanAmount":123.123
|
||||
}
|
||||
"""
|
||||
)
|
||||
headers {
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
|
||||
}
|
||||
response {
|
||||
status OK()
|
||||
body(
|
||||
fraudCheckStatus: "OK",
|
||||
rejectionReason: $(consumer(null), producer(execute('assertThatRejectionReasonIsNull($it)')))
|
||||
)
|
||||
headers {
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user