[JAVA-10500] Investigate and reduce springdoc build time

This commit is contained in:
Haroon Khan 2022-03-19 18:27:30 +00:00
parent ac99726577
commit 10bde9d0af
6 changed files with 66 additions and 109 deletions

View File

@ -37,10 +37,6 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<!-- SpringDoc --> <!-- SpringDoc -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
@ -63,21 +59,6 @@
<artifactId>spring-restdocs-restassured</artifactId> <artifactId>spring-restdocs-restassured</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!--kotlin dependencies -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-kotlin</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -109,41 +90,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<!-- kotlin -->
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
<jvmTarget>${java.version}</jvmTarget>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins> </plugins>
<resources> <resources>
<resource> <resource>
@ -208,7 +154,6 @@
<properties> <properties>
<springdoc.version>1.6.4</springdoc.version> <springdoc.version>1.6.4</springdoc.version>
<asciidoctor-plugin.version>1.5.6</asciidoctor-plugin.version> <asciidoctor-plugin.version>1.5.6</asciidoctor-plugin.version>
<kotlin.version>1.6.0</kotlin.version>
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory> <snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
</properties> </properties>

View File

@ -40,7 +40,8 @@ public class FooController {
public ResponseEntity<Foo> getFooById(@PathVariable("id") Long id) { public ResponseEntity<Foo> getFooById(@PathVariable("id") Long id) {
Optional<Foo> foo = repository.findById(id); Optional<Foo> foo = repository.findById(id);
return foo.isPresent() ? new ResponseEntity<>(foo.get(), HttpStatus.OK) : new ResponseEntity<>(HttpStatus.NOT_FOUND); return foo.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
} }
@PostMapping @PostMapping
@ -70,7 +71,7 @@ public class FooController {
@PutMapping("/{id}") @PutMapping("/{id}")
public ResponseEntity<Foo> updateFoo(@PathVariable("id") long id, @RequestBody Foo foo) { public ResponseEntity<Foo> updateFoo(@PathVariable("id") long id, @RequestBody Foo foo) {
boolean isFooPresent = repository.existsById(Long.valueOf(id)); boolean isFooPresent = repository.existsById(id);
if (!isFooPresent) { if (!isFooPresent) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND); return new ResponseEntity<>(HttpStatus.NOT_FOUND);

View File

@ -7,10 +7,7 @@
</encoder> </encoder>
</appender> </appender>
<logger name="org.springframework" level="DEBUG" /> <root level="WARN">
<logger name="org.springframework.transaction" level="WARN" />
<root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</root> </root>
</configuration> </configuration>

View File

@ -1,6 +1,32 @@
package com.baeldung.restdocopenapi.restdoc; package com.baeldung.restdocopenapi.restdoc;
import com.baeldung.restdocopenapi.Foo;
import com.baeldung.restdocopenapi.FooController;
import com.baeldung.restdocopenapi.FooRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
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.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.hateoas.MediaTypes;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.constraints.ConstraintDescriptions;
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 java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
@ -15,99 +41,89 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.requestF
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.util.StringUtils.collectionToDelimitedString; 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 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.restdocopenapi.Application;
import com.baeldung.restdocopenapi.Foo;
import com.fasterxml.jackson.databind.ObjectMapper;
@ExtendWith({ RestDocumentationExtension.class, SpringExtension.class }) @ExtendWith({ RestDocumentationExtension.class, SpringExtension.class })
@SpringBootTest(classes = Application.class) @WebMvcTest(FooController.class)
public class SpringRestDocsUnitTest { class SpringRestDocsUnitTest {
private MockMvc mockMvc; private MockMvc mockMvc;
@MockBean
private FooRepository fooRepository;
@Autowired @Autowired
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@BeforeEach @BeforeEach
public void setup(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) { void setup(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation)) .apply(documentationConfiguration(restDocumentation))
.build(); .build();
} }
@Test @Test
public void whenGetFoo_thenSuccessful() throws Exception { void whenGetAllFoo_thenSuccessful() throws Exception {
when(fooRepository.findAll())
.thenReturn(singletonList(new Foo(1, "Foo 1", "Foo 1")));
this.mockMvc.perform(get("/foo")) this.mockMvc.perform(get("/foo"))
.andDo(print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().string(containsString("Foo 1"))) .andExpect(content().string(containsString("Foo 1")))
.andDo(document("getAllFoos")); .andDo(document("getAllFoos"));
} }
@Test @Test
public void whenGetFooById_thenSuccessful() throws Exception { void whenGetFooById_thenSuccessful() throws Exception {
ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class); ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class);
when(fooRepository.findById(1L))
.thenReturn(Optional.of(new Foo(1, "title", "body")));
this.mockMvc.perform(get("/foo/{id}", 1)) this.mockMvc.perform(get("/foo/{id}", 1))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andDo(document("getAFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), .andDo(document("getAFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()),
pathParameters(parameterWithName("id").description("id of foo to be searched")), pathParameters(parameterWithName("id").description("id of foo to be searched")),
responseFields(fieldWithPath("id").description("The id of the foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")), responseFields(fieldWithPath("id").description("The id of the foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")),
fieldWithPath("title").description("The title of the foo"), fieldWithPath("body").description("The body of the foo")))); fieldWithPath("title").description("The title of the foo"), fieldWithPath("body").description("The body of the foo"))));
} }
@Test @Test
public void whenPostFoo_thenSuccessful() throws Exception { void whenPostFoo_thenSuccessful() throws Exception {
Map<String, Object> foo = new HashMap<>(); Map<String, Object> foo = new HashMap<>();
foo.put("id", 4L); foo.put("id", 4L);
foo.put("title", "New Foo"); foo.put("title", "New Foo");
foo.put("body", "Body of New Foo"); foo.put("body", "Body of New Foo");
this.mockMvc.perform(post("/foo").contentType(MediaTypes.HAL_JSON) this.mockMvc.perform(post("/foo").contentType(MediaTypes.HAL_JSON)
.content(this.objectMapper.writeValueAsString(foo))) .content(this.objectMapper.writeValueAsString(foo)))
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andDo(document("createFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the foo"), fieldWithPath("title").description("The title of the foo"), .andDo(document("createFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields(fieldWithPath("id").description("The id of the foo"), fieldWithPath("title").description("The title of the foo"),
fieldWithPath("body").description("The body of the foo")))); fieldWithPath("body").description("The body of the foo"))));
} }
@Test @Test
public void whenDeleteFoo_thenSuccessful() throws Exception { void whenDeleteFoo_thenSuccessful() throws Exception {
this.mockMvc.perform(delete("/foo/{id}", 2)) this.mockMvc.perform(delete("/foo/{id}", 2))
.andExpect(status().isNoContent()) .andExpect(status().isNoContent())
.andDo(document("deleteFoo", pathParameters(parameterWithName("id").description("The id of the foo to delete")))); .andDo(document("deleteFoo", pathParameters(parameterWithName("id").description("The id of the foo to delete"))));
} }
@Test @Test
public void whenUpdateFoo_thenSuccessful() throws Exception { void whenUpdateFoo_thenSuccessful() throws Exception {
when(fooRepository.existsById(3L)).thenReturn(true);
when(fooRepository.save(any(Foo.class)))
.thenReturn(new Foo(3, "Updated Foo", "Body of updated Foo"));
ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class); ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class);
Map<String, Object> foo = new HashMap<>(); Map<String, Object> foo = new HashMap<>();
foo.put("title", "Updated Foo"); foo.put("title", "Updated Foo");
foo.put("body", "Body of Updated Foo"); foo.put("body", "Body of Updated Foo");
this.mockMvc.perform(put("/foo/{id}", 3).contentType(MediaTypes.HAL_JSON) this.mockMvc.perform(put("/foo/{id}", 3).contentType(MediaTypes.HAL_JSON)
.content(this.objectMapper.writeValueAsString(foo))) .content(this.objectMapper.writeValueAsString(foo)))
.andExpect(status().isOk()) .andExpect(status().isOk())
@ -115,6 +131,4 @@ public class SpringRestDocsUnitTest {
responseFields(fieldWithPath("id").description("The id of the updated foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")), responseFields(fieldWithPath("id").description("The id of the updated foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")),
fieldWithPath("title").description("The title of the updated foo"), fieldWithPath("body").description("The body of the updated foo")))); fieldWithPath("title").description("The title of the updated foo"), fieldWithPath("body").description("The body of the updated foo"))));
} }
} }

View File

@ -1,17 +1,17 @@
package com.baeldung.springdoc; package com.baeldung.springdoc;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit.jupiter.SpringExtension;
@RunWith(SpringRunner.class) @ExtendWith(SpringExtension.class)
@SpringBootTest @SpringBootTest
public class SpringContextTest { class SpringContextTest {
@Test @Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() { void whenSpringContextIsBootstrapped_thenNoExceptions() {
} }
} }