diff --git a/spring-5/pom.xml b/spring-5/pom.xml
index 81e7ae3123..a76730f628 100644
--- a/spring-5/pom.xml
+++ b/spring-5/pom.xml
@@ -139,7 +139,8 @@
${junit.platform.version}
test
-
+
+
org.springframework.restdocs
spring-restdocs-mockmvc
test
@@ -183,7 +184,7 @@
-
+
org.asciidoctor
asciidoctor-maven-plugin
${asciidoctor-plugin.version}
diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java
new file mode 100644
index 0000000000..de1d3f8b6a
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java
@@ -0,0 +1,184 @@
+package com.baeldung.restdocs;
+
+import com.baeldung.restdocs.CrudInput;
+import com.baeldung.restdocs.SpringRestDocsApplication;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.hateoas.MediaTypes;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.restdocs.constraints.ConstraintDescriptions;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static java.util.Collections.singletonList;
+import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
+import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
+import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
+import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
+import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
+import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.util.StringUtils.collectionToDelimitedString;
+import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
+import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
+import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = SpringRestDocsApplication.class)
+public class ApiDocumentationJUnit4IntegrationTest {
+
+ @Rule
+ public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");
+
+ @Autowired
+ private WebApplicationContext context;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setUp() {
+
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+ .apply(documentationConfiguration(this.restDocumentation))
+ .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+ .build();
+ }
+
+ @Test
+ public void indexExample() throws Exception {
+ this.mockMvc.perform(get("/"))
+ .andExpect(status().isOk())
+ .andDo(document("index-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links").description("Links to other resources")),
+ responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`"))));
+ }
+
+ @Test
+ public void crudGetExample() throws Exception {
+
+ Map tag = new HashMap<>();
+ tag.put("name", "GET");
+
+ String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("id", 1L);
+ crud.put("title", "Sample Model");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ ConstraintDescriptions desc = new ConstraintDescriptions(CrudInput.class);
+
+ this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isOk())
+ .andDo(document("crud-get-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")),
+ fieldWithPath("title").description("The title of the input"), fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs"))));
+ }
+
+ @Test
+ public void crudCreateExample() throws Exception {
+ Map tag = new HashMap<>();
+ tag.put("name", "CREATE");
+
+ String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isCreated())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("id", 2L);
+ crud.put("title", "Sample Model");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isCreated())
+ .andDo(document("crud-create-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input"), fieldWithPath("title").description("The title of the input"),
+ fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs"))));
+ }
+
+ @Test
+ public void crudDeleteExample() throws Exception {
+ this.mockMvc.perform(delete("/crud/{id}", 10))
+ .andExpect(status().isOk())
+ .andDo(document("crud-delete-example", pathParameters(parameterWithName("id").description("The id of the input to delete"))));
+ }
+
+ @Test
+ public void crudPatchExample() throws Exception {
+
+ Map tag = new HashMap<>();
+ tag.put("name", "PATCH");
+
+ String tagLocation = this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("title", "Sample Model Patch");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void crudPutExample() throws Exception {
+ Map tag = new HashMap<>();
+ tag.put("name", "PUT");
+
+ String tagLocation = this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isAccepted())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("title", "Sample Model");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isAccepted());
+ }
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java
new file mode 100644
index 0000000000..d915a4fdde
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java
@@ -0,0 +1,181 @@
+package com.baeldung.restdocs;
+
+import static java.util.Collections.singletonList;
+import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
+import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
+import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
+import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
+import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
+import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
+import static org.springframework.restdocs.request.RequestDocumentation.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.util.StringUtils.collectionToDelimitedString;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.hateoas.MediaTypes;
+import org.springframework.restdocs.RestDocumentationContextProvider;
+import org.springframework.restdocs.RestDocumentationExtension;
+import org.springframework.restdocs.constraints.ConstraintDescriptions;
+import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import com.baeldung.restdocs.CrudInput;
+import com.baeldung.restdocs.SpringRestDocsApplication;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@ExtendWith({ RestDocumentationExtension.class, SpringExtension.class })
+@SpringBootTest(classes = SpringRestDocsApplication.class)
+public class ApiDocumentationJUnit5IntegrationTest {
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ public void setUp(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
+ .apply(documentationConfiguration(restDocumentation))
+ .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+ .build();
+ }
+
+ @Test
+ public void indexExample() throws Exception {
+ this.mockMvc.perform(get("/"))
+ .andExpect(status().isOk())
+ .andDo(document("index-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), links(linkWithRel("crud").description("The CRUD resource")), responseFields(subsectionWithPath("_links").description("Links to other resources")),
+ responseHeaders(headerWithName("Content-Type").description("The Content-Type of the payload, e.g. `application/hal+json`"))));
+ }
+
+ @Test
+ public void crudGetExample() throws Exception {
+
+ Map tag = new HashMap<>();
+ tag.put("name", "GET");
+
+ String tagLocation = this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("id", 1L);
+ crud.put("title", "Sample Model");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ ConstraintDescriptions desc = new ConstraintDescriptions(CrudInput.class);
+
+ this.mockMvc.perform(get("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isOk())
+ .andDo(document("crud-get-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")),
+ fieldWithPath("title").description("The title of the input"), fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs"))));
+ }
+
+ @Test
+ public void crudCreateExample() throws Exception {
+ Map tag = new HashMap<>();
+ tag.put("name", "CREATE");
+
+ String tagLocation = this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isCreated())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("id", 2L);
+ crud.put("title", "Sample Model");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ this.mockMvc.perform(post("/crud").contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isCreated())
+ .andDo(document("crud-create-example", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the input"), fieldWithPath("title").description("The title of the input"),
+ fieldWithPath("body").description("The body of the input"), fieldWithPath("tags").description("An array of tag resource URIs"))));
+ }
+
+ @Test
+ public void crudDeleteExample() throws Exception {
+ this.mockMvc.perform(delete("/crud/{id}", 10))
+ .andExpect(status().isOk())
+ .andDo(document("crud-delete-example", pathParameters(parameterWithName("id").description("The id of the input to delete"))));
+ }
+
+ @Test
+ public void crudPatchExample() throws Exception {
+
+ Map tag = new HashMap<>();
+ tag.put("name", "PATCH");
+
+ String tagLocation = this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("title", "Sample Model Patch");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ this.mockMvc.perform(patch("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void crudPutExample() throws Exception {
+ Map tag = new HashMap<>();
+ tag.put("name", "PUT");
+
+ String tagLocation = this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(tag)))
+ .andExpect(status().isAccepted())
+ .andReturn()
+ .getResponse()
+ .getHeader("Location");
+
+ Map crud = new HashMap<>();
+ crud.put("title", "Sample Model");
+ crud.put("body", "http://www.baeldung.com/");
+ crud.put("tags", singletonList(tagLocation));
+
+ this.mockMvc.perform(put("/crud/{id}", 10).contentType(MediaTypes.HAL_JSON)
+ .content(this.objectMapper.writeValueAsString(crud)))
+ .andExpect(status().isAccepted());
+ }
+
+ @Test
+ public void contextLoads() {
+ }
+
+}