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 org.springframework.web.util.NestedServletException;
import java.net.URI;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.*;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
}
@Test
- void test400ForNegativeAnswer_NOT_WORKING() throws Exception {
+ void testExceptionForNegativeAnswer() 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()
- // on the empty Optional and wrapped by Thymeleaf in a TemplateProcessingException
- // is catched by the @ExceptionHandler, that is defined in the ExampleController
- // and reported as 400: Bad Request.
- // 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=1234")))
- .andExpect(status().isBadRequest())
- .andDo((result) -> {
- String content = result.getResponse().getContentAsString();
- Document doc = Jsoup.parse(content);
- assertThat(doc.selectFirst("div:nth-child(2)").text())
- .isEqualTo("There was an unexpected error (type=Internal Server Error, status=400).");
- });
+ // The corrected version of the test catches the wrapper NestedServletException
+ // for exceptions, that are handled in the DispatcherServlet in a fully setup
+ // and, hence, cannot be handled in a @WebMvcTest, that mocks this part of the stack.
+ assertThrows(
+ NestedServletException.class,
+ () -> mvc.perform(get(URI.create("http://FOO/?answer=1234"))));
verify(service, times(1)).checkAnswer(anyInt());
}
@Test
- void test400ForStringInput_NOT_WORKING() throws Exception {
+ void test400ForStringInput() throws Exception {
when(service.checkAnswer(anyInt())).thenReturn(Optional.empty());
// The expected behaviour of the following test is, that the WhiteLabel Error Page
// Instead, an almost empty page is rendered for the error.
mvc
.perform(get(URI.create("http://FOO/?answer=bar")))
- .andExpect(status().isBadRequest())
- .andDo((result) -> {
- String content = result.getResponse().getContentAsString();
- Document doc = Jsoup.parse(content);
- assertThat(doc.selectFirst("div:nth-child(2)").text())
- .isEqualTo("There was an unexpected error (type=Internal Server Error, status=400).");
- });
+ .andExpect(status().isBadRequest());
+ // Specifying exceptations for the rendered output is not useful,
+ // because MockMvc does not render the White Label ErrorPage
verify(service, times(0)).checkAnswer(anyInt());
}