From c8d1c555000b34d2bdd97b4ae385405b36311dd3 Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Wed, 30 Sep 2020 08:42:38 +0200 Subject: [PATCH] Refined the test: @ParameterizedTest adds no additional insight here * The parameterized tests only test the difference between an empty and an non-empty Optional. * The actual number is meaningless, because the business logic is mocked away anyway! * Hence, the parameterized version only tests the correctness of our mocking: The test could only fail, if we make a mistake in the setup of the expectations, not in the code under test! * Also splitted up some test-cases more logically. --- .../java/de/juplo/demo/ExampleController.java | 6 +- .../ExceptionHandlingApplicationTests.java | 69 ++++++++++++------- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/main/java/de/juplo/demo/ExampleController.java b/src/main/java/de/juplo/demo/ExampleController.java index d919b63..de806ef 100644 --- a/src/main/java/de/juplo/demo/ExampleController.java +++ b/src/main/java/de/juplo/demo/ExampleController.java @@ -5,10 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.DispatcherServlet; import org.thymeleaf.exceptions.TemplateProcessingException; import java.util.Optional; diff --git a/src/test/java/de/juplo/demo/ExceptionHandlingApplicationTests.java b/src/test/java/de/juplo/demo/ExceptionHandlingApplicationTests.java index a80ffd3..65d3e4a 100644 --- a/src/test/java/de/juplo/demo/ExceptionHandlingApplicationTests.java +++ b/src/test/java/de/juplo/demo/ExceptionHandlingApplicationTests.java @@ -1,8 +1,6 @@ package de.juplo.demo; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -13,9 +11,7 @@ import org.springframework.test.web.servlet.MockMvc; import java.net.URI; import java.util.Optional; -import static org.mockito.AdditionalMatchers.geq; -import static org.mockito.AdditionalMatchers.lt; -import static org.mockito.ArgumentMatchers.*; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -45,24 +41,49 @@ class ExceptionHandlingApplicationTests { verify(service, times(0)).checkAnswer(anyInt()); } - @ParameterizedTest - @ValueSource(ints = { 0, 1, 2, 3, 4, 5, 41, 42, 43, 666, Integer.MAX_VALUE }) - void test200ForPositiveAnswer(int number) throws Exception { - when(service.checkAnswer(eq(42))).thenReturn(Optional.of(true)); - when(service.checkAnswer(geq(0))).thenReturn(Optional.of(false)); - when(service.checkAnswer(lt(0))).thenReturn(Optional.empty()); + @Test + void test200ForEmptyAnswer() throws Exception { + mvc + .perform(get(URI.create("http://FOO/?answer="))) + .andExpect(status().isOk()); + + verify(service, times(0)).checkAnswer(anyInt()); + } + + @Test + void test200ForAnswerThatContainsOnlyWhitespace() throws Exception { + mvc + .perform(get(URI.create("http://FOO/?answer=%20"))) + .andExpect(status().isOk()); + + verify(service, times(0)).checkAnswer(anyInt()); + } + + @Test + void test200ForWrongAnswer() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.of(false)); + + mvc + .perform(get(URI.create("http://FOO/?answer=1234"))) + .andExpect(status().isOk()); + + verify(service, times(1)).checkAnswer(anyInt()); + } + + @Test + void test200ForCorrectAnswer() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.of(true)); mvc - .perform(get(URI.create("http://FOO/?answer=" + number))) + .perform(get(URI.create("http://FOO/?answer=1234"))) .andExpect(status().isOk()); + + verify(service, times(1)).checkAnswer(anyInt()); } - @ParameterizedTest - @ValueSource(ints = { -1, -2, Integer.MIN_VALUE }) - void test400ForNegativeAnswer_NOT_WORKING(int number) throws Exception { - when(service.checkAnswer(eq(42))).thenReturn(Optional.of(true)); - when(service.checkAnswer(geq(0))).thenReturn(Optional.of(false)); - when(service.checkAnswer(lt(0))).thenReturn(Optional.empty()); + @Test + void test400ForNegativeAnswer_NOT_WORKING() throws Exception { + when(service.checkAnswer(anyInt())).thenReturn(Optional.empty()); // The expected behaviour of the following test is, that the NoSuchElementException // with the message "No value present", that is raised, when the view calls .get() @@ -72,18 +93,20 @@ class ExceptionHandlingApplicationTests { // Instead, the exception bubbles up, becomes wrapped in a NestedServletException // and is thrown in the call to perform()! mvc - .perform(get(URI.create("http://FOO/?answer=" + number))) - .andExpect(status().isInternalServerError()); + .perform(get(URI.create("http://FOO/?answer=1234"))) + .andExpect(status().isBadRequest()); + + verify(service, times(1)).checkAnswer(anyInt()); } @Test void test400ForStringInput() throws Exception { - when(service.checkAnswer(eq(42))).thenReturn(Optional.of(true)); - when(service.checkAnswer(geq(0))).thenReturn(Optional.of(false)); - when(service.checkAnswer(lt(0))).thenReturn(Optional.empty()); + when(service.checkAnswer(anyInt())).thenReturn(Optional.empty()); mvc .perform(get(URI.create("http://FOO/?answer=bar"))) .andExpect(status().isBadRequest()); + + verify(service, times(0)).checkAnswer(anyInt()); } } -- 2.20.1