From 42b277722bd51cb8456914e0c7ad3c40f3cd52cd Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Sat, 19 Sep 2020 14:08:38 +0200 Subject: [PATCH] Added an integration-test that tests the exception-handling * The integration-test uses WebTestClient to test the exception-handling * Since this is a real integration-test, the exception-handling behave exactly the same way * The test-setup with the WebTestClient needs an additional dependency, to work correctly - without it, the WebTestClient-Bean would not be intanciated * The added test ExceptionHandlingApplicationIT tests exaclty the same stuff, as ExceptionHandlingApplicationTest - this is no good test-design, but it serves the intention, to compare the two approaches * Since Spring-Boot configures the surefire-maven-plugin to ignore all tests, that end with IT, the failsafe-maven-plugin has to be added to automatically fire the new test - remember: you have to call "mvn verify" to fire IT --- pom.xml | 9 + .../demo/ExceptionHandlingApplicationIT.java | 185 ++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 src/test/java/de/juplo/demo/ExceptionHandlingApplicationIT.java diff --git a/pom.xml b/pom.xml index 9e6ae90..299903c 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,11 @@ 1.13.1 test + + org.springframework.boot + spring-boot-starter-webflux + test + @@ -58,6 +63,10 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-failsafe-plugin + diff --git a/src/test/java/de/juplo/demo/ExceptionHandlingApplicationIT.java b/src/test/java/de/juplo/demo/ExceptionHandlingApplicationIT.java new file mode 100644 index 0000000..d964e6c --- /dev/null +++ b/src/test/java/de/juplo/demo/ExceptionHandlingApplicationIT.java @@ -0,0 +1,185 @@ +package de.juplo.demo; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.*; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@AutoConfigureWebTestClient +class ExceptionHandlingApplicationIT { + private final static Logger LOG = + LoggerFactory.getLogger(ExceptionHandlingApplicationIT.class); + + @MockBean + ExampleService service; + + @Autowired + WebTestClient client; + + + @Test + void contextLoads() throws Exception { + } + + @Test + void test200ForNoAnswer() throws Exception { + client + .get() + .uri("/") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.select("ul > li")).isEmpty(); + }); + + verify(service, times(0)).checkAnswer(anyInt()); + } + + @Test + void test200ForEmptyAnswer() throws Exception { + client + .get() + .uri("/?answer= ") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.select("ul > li")).isEmpty(); + }); + + verify(service, times(0)).checkAnswer(anyInt()); + } + + @Test + void test200ForAnswerThatContainsOnlyWhitespace() throws Exception { + client + .get() + .uri("/?answer=") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.select("ul > li")).isEmpty(); + }); + + verify(service, times(0)).checkAnswer(anyInt()); + } + + @Test + void test200ForWrongAnswer() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.of(false)); + + client + .get() + .uri("/?answer=1234") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.selectFirst("ul > li:nth-child(2) > strong").text()).isEqualTo("false"); + }); + + verify(service, times(1)).checkAnswer(anyInt()); + } + + @Test + void test200ForCorrectAnswer() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.of(true)); + + client + .get() + .uri("/?answer=1234") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isOk() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.selectFirst("ul > li:nth-child(2) > strong").text()).isEqualTo("true"); + }); + + verify(service, times(1)).checkAnswer(anyInt()); + } + + @Test + void testExceptionForNegativeAnswer() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.empty()); + + client + .get() + .uri("/?answer=1234") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR) + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.selectFirst("title").text()) + .isEqualTo("500: Internal Server Error"); + assertThat(doc.selectFirst("div > p > strong").text()) + .isEqualTo("Catched exception: java.lang.IllegalArgumentException: FOO!"); + }); + + verify(service, times(1)).checkAnswer(anyInt()); + } + + @Test + void test400ForStringInput() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.empty()); + + client + .get() + .uri("/?answer=bar") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isBadRequest() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.selectFirst("title").text()) + .isEqualTo("400: NumberFormatException"); + assertThat(doc.selectFirst("div > p > strong").text()) + .isEqualTo("Catched exception: java.lang.NumberFormatException: For input string: \"bar\""); + }); + + verify(service, times(0)).checkAnswer(anyInt()); + } + + @Test + void test400ForExceptionInBusinessLogic() throws Exception { + when(service.checkAnswer(anyInt())).thenThrow(new IllegalArgumentException("FOO!")); + + client + .get() + .uri("/?answer=1234") + .accept(MediaType.TEXT_HTML) + .exchange() + .expectStatus().isBadRequest() + .expectBody(String.class).value(content -> { + Document doc = Jsoup.parse(content); + assertThat(doc.selectFirst("title").text()) + .isEqualTo("400: IllegalArgumentException"); + assertThat(doc.selectFirst("div > p > strong").text()) + .isEqualTo("Catched exception: java.lang.IllegalArgumentException: FOO!"); + }); + + verify(service, times(1)).checkAnswer(anyInt()); + } +} -- 2.20.1