Refined the test: @ParameterizedTest adds no additional insight here
authorKai Moritz <kai@juplo.de>
Wed, 30 Sep 2020 06:42:38 +0000 (08:42 +0200)
committerKai Moritz <kai@juplo.de>
Fri, 2 Oct 2020 17:18:50 +0000 (19:18 +0200)
* 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.

src/main/java/de/juplo/demo/ExampleController.java
src/test/java/de/juplo/demo/ExceptionHandlingApplicationTests.java

index d919b63..de806ef 100644 (file)
@@ -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;
index a80ffd3..65d3e4a 100644 (file)
@@ -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());
        }
 }