import org.springframework.web.bind.annotation.ResponseStatus;
import org.thymeleaf.exceptions.TemplateInputException;
+import java.util.Optional;
+
@Controller
public class ExampleController
{
LoggerFactory.getLogger(ExampleController.class);
+ private final ExampleService service;
+
+
+ public ExampleController(ExampleService service)
+ {
+ this.service = service;
+ }
+
+
@RequestMapping("/")
public String controller(
- @RequestParam(defaultValue = "a") String template,
+ @RequestParam(required = false) Integer answer,
Model model
)
{
- model.addAttribute("template", template);
- return template;
+ Optional<Boolean> outcome =
+ answer == null ? null : service.checkAnswer(answer);
+
+ model.addAttribute("answer", answer);
+ model.addAttribute("outcome", outcome);
+ return "view";
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+++ /dev/null
-<!DOCTYPE HTML>
-<html xmlns:th="http://www.thymeleaf.org">
- <head>
- <title>Testing Exception-Handling - Template A</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- </head>
- <body>
- <h1>Template A</h1>
- <div>
- <p><strong th:text="'Serving with template ::' + ${template} + '::!'">TEXT</strong></p>
- <p>
- Type in <strong><code>a</code></strong> or <strong><code>b</code></strong>
- for an existing template (no exception). Type in any other string for a
- non-existent template: Thymeleaf will throw a
- <strong><code>TemplateInputException</code></strong>!
- </p>
- </div>
- <div>
- <form action="#" th:action="@{/}" method="get">
- <div>
- <label for="path">Remote-Path to fetch:</label>
- <input type="text" name="template" value="a" th:value="${template}"/>
- </div>
- <button type="submit">Submit</button>
- </form>
- </div>
- </body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML>
-<html xmlns:th="http://www.thymeleaf.org">
- <head>
- <title>Testing Exception-Handling - Template B</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- </head>
- <body>
- <h1>Template B</h1>
- <div>
- <p><strong th:text="'Serving with template ::' + ${template} + '::!'">TEXT</strong></p>
- <p>
- Type in <strong><code>a</code></strong> or <strong><code>b</code></strong>
- for an existing template (no exception). Type in any other string for a
- non-existent template: Thymeleaf will throw a
- <strong><code>TemplateInputException</code></strong>!
- </p>
- </div>
- <div>
- <form action="#" th:action="@{/}" method="get">
- <div>
- <label for="path">Remote-Path to fetch:</label>
- <input type="text" name="template" value="a" th:value="${template}"/>
- </div>
- <button type="submit">Submit</button>
- </form>
- </div>
- </body>
-</html>
--- /dev/null
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+ <head>
+ <title>Template: view</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ </head>
+ <body>
+ <h1>Deeep Thought</h1>
+ <div th:switch="${answer}">
+ <p th:case="null">
+ <strong>What is the answer to the ultimate question of life, the universe and everything?</strong>
+ </p>
+ <ul th:case="*">
+ <li>Presented answer: <strong th:text="${answer}">ANSWER</strong></li>
+ <li>Outcome: <strong th:text="${outcome.get()}">OUTCOME</strong></li>
+ </ul>
+ </div>
+ <div>
+ <form action="#" th:action="@{/}" method="get">
+ <div>
+ <label for="answer">Answer:</label>
+ <input type="text" name="answer" value="42" th:value="${answer}"/>
+ <button type="submit">Submit</button>
+ </div>
+ </form>
+ </div>
+ </body>
+</html>
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.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.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.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
private final static Logger LOG =
LoggerFactory.getLogger(ExceptionHandlingApplicationTests.class);
+ @MockBean
+ ExampleService service;
+
@Autowired
MockMvc mvc;
}
@Test
- void test200() throws Exception {
+ void test200ForNoAnswer() throws Exception {
mvc
- .perform(get(URI.create("http://FOO/?template=a")))
+ .perform(get(URI.create("http://FOO/")))
.andExpect(status().isOk());
+
+ 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());
+
mvc
- .perform(get(URI.create("http://FOO/?template=b")))
+ .perform(get(URI.create("http://FOO/?answer=" + number)))
.andExpect(status().isOk());
}
- @Test
- void test503_NOT_WORKING() throws Exception {
+ @ParameterizedTest
+ @ValueSource(ints = { -1, -2, Integer.MIN_VALUE })
+ void test500ForNegativeAnswer_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());
+
// The expected behaviour of the following test is, that the
// TemplateInputException, that is thrown by Thymeleaf because of the non-existent
// template-resource, is catched and reported as 503 Internal Server Error, as it
// 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/?template=foo")))
+ .perform(get(URI.create("http://FOO/?answer=" + number)))
.andExpect(status().isInternalServerError());
}
+
+ @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());
+
+ mvc
+ .perform(get(URI.create("http://FOO/?answer=bar")))
+ .andExpect(status().isBadRequest());
+ }
}