Skip to content

Commit 9fcdaa7

Browse files
committed
Regression tests for @RestControllerAdvice support in MockMvc
This commit introduces regression tests for @RestControllerAdvice support in standalone MockMvc configurations. See gh-25520
1 parent ef64945 commit 9fcdaa7

File tree

1 file changed

+125
-8
lines changed

1 file changed

+125
-8
lines changed

spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ExceptionHandlerTests.java

Lines changed: 125 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,12 +18,16 @@
1818

1919
import org.junit.Test;
2020

21+
import org.springframework.core.Ordered;
22+
import org.springframework.core.annotation.Order;
23+
import org.springframework.http.MediaType;
2124
import org.springframework.stereotype.Controller;
2225
import org.springframework.web.bind.annotation.ControllerAdvice;
2326
import org.springframework.web.bind.annotation.ExceptionHandler;
27+
import org.springframework.web.bind.annotation.GetMapping;
2428
import org.springframework.web.bind.annotation.PathVariable;
25-
import org.springframework.web.bind.annotation.RequestMapping;
26-
import org.springframework.web.bind.annotation.RequestMethod;
29+
import org.springframework.web.bind.annotation.RestController;
30+
import org.springframework.web.bind.annotation.RestControllerAdvice;
2731

2832
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
2933
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@@ -33,30 +37,78 @@
3337
* Exception handling via {@code @ExceptionHandler} method.
3438
*
3539
* @author Rossen Stoyanchev
40+
* @author Sam Brannen
3641
*/
3742
public class ExceptionHandlerTests {
3843

3944
@Test
40-
public void testExceptionHandlerMethod() throws Exception {
45+
public void mvcLocalExceptionHandlerMethod() throws Exception {
4146
standaloneSetup(new PersonController()).build()
42-
.perform(get("/person/Clyde"))
47+
.perform(get("/person/Clyde"))
4348
.andExpect(status().isOk())
4449
.andExpect(forwardedUrl("errorView"));
4550
}
4651

4752
@Test
48-
public void testGlobalExceptionHandlerMethod() throws Exception {
53+
public void mvcGlobalExceptionHandlerMethod() throws Exception {
4954
standaloneSetup(new PersonController()).setControllerAdvice(new GlobalExceptionHandler()).build()
5055
.perform(get("/person/Bonnie"))
5156
.andExpect(status().isOk())
5257
.andExpect(forwardedUrl("globalErrorView"));
5358
}
5459

60+
@Test
61+
public void restNoException() throws Exception {
62+
standaloneSetup(new RestPersonController())
63+
.setControllerAdvice(new RestGlobalExceptionHandler(), new RestPersonControllerExceptionHandler()).build()
64+
.perform(get("/person/Yoda").accept(MediaType.APPLICATION_JSON))
65+
.andExpect(status().isOk())
66+
.andExpect(jsonPath("$.name").value("Yoda"));
67+
}
68+
69+
@Test
70+
public void restLocalExceptionHandlerMethod() throws Exception {
71+
standaloneSetup(new RestPersonController())
72+
.setControllerAdvice(new RestGlobalExceptionHandler(), new RestPersonControllerExceptionHandler()).build()
73+
.perform(get("/person/Luke").accept(MediaType.APPLICATION_JSON))
74+
.andExpect(status().isOk())
75+
.andExpect(jsonPath("$.error").value("local - IllegalArgumentException"));
76+
}
77+
78+
@Test
79+
public void restGlobalExceptionHandlerMethod() throws Exception {
80+
standaloneSetup(new RestPersonController())
81+
.setControllerAdvice(new RestGlobalExceptionHandler()).build()
82+
.perform(get("/person/Leia").accept(MediaType.APPLICATION_JSON))
83+
.andExpect(status().isOk())
84+
.andExpect(jsonPath("$.error").value("global - IllegalStateException"));
85+
}
86+
87+
@Test
88+
public void restGlobalRestPersonControllerExceptionHandlerTakesPrecedenceOverGlobalExceptionHandler() throws Exception {
89+
standaloneSetup(new RestPersonController())
90+
.setControllerAdvice(new RestGlobalExceptionHandler(), new RestPersonControllerExceptionHandler()).build()
91+
.perform(get("/person/Leia").accept(MediaType.APPLICATION_JSON))
92+
.andExpect(status().isOk())
93+
.andExpect(jsonPath("$.error").value("globalPersonController - IllegalStateException"));
94+
}
95+
96+
@Test // gh-25520
97+
public void restNoHandlerFound() throws Exception {
98+
standaloneSetup(new RestPersonController())
99+
.setControllerAdvice(new RestGlobalExceptionHandler(), new RestPersonControllerExceptionHandler())
100+
.addDispatcherServletCustomizer(dispatcherServlet -> dispatcherServlet.setThrowExceptionIfNoHandlerFound(true))
101+
.build()
102+
.perform(get("/bogus").accept(MediaType.APPLICATION_JSON))
103+
.andExpect(status().isOk())
104+
.andExpect(jsonPath("$.error").value("global - NoHandlerFoundException"));
105+
}
106+
55107

56108
@Controller
57109
private static class PersonController {
58110

59-
@RequestMapping(value="/person/{name}", method=RequestMethod.GET)
111+
@GetMapping("/person/{name}")
60112
public String show(@PathVariable String name) {
61113
if (name.equals("Clyde")) {
62114
throw new IllegalArgumentException("simulated exception");
@@ -73,15 +125,80 @@ public String handleException(IllegalArgumentException exception) {
73125
}
74126
}
75127

76-
77128
@ControllerAdvice
78129
private static class GlobalExceptionHandler {
79130

80131
@ExceptionHandler
81132
public String handleException(IllegalStateException exception) {
82133
return "globalErrorView";
83134
}
135+
}
136+
137+
@RestController
138+
private static class RestPersonController {
139+
140+
@GetMapping("/person/{name}")
141+
Person get(@PathVariable String name) {
142+
switch (name) {
143+
case "Luke":
144+
throw new IllegalArgumentException();
145+
case "Leia":
146+
throw new IllegalStateException();
147+
default:
148+
return new Person("Yoda");
149+
}
150+
}
151+
152+
@ExceptionHandler
153+
Error handleException(IllegalArgumentException exception) {
154+
return new Error("local - " + exception.getClass().getSimpleName());
155+
}
156+
}
157+
158+
@RestControllerAdvice(assignableTypes = RestPersonController.class)
159+
@Order(Ordered.HIGHEST_PRECEDENCE)
160+
private static class RestPersonControllerExceptionHandler {
161+
162+
@ExceptionHandler
163+
Error handleException(Throwable exception) {
164+
return new Error("globalPersonController - " + exception.getClass().getSimpleName());
165+
}
166+
}
167+
168+
@RestControllerAdvice
169+
@Order(Ordered.LOWEST_PRECEDENCE)
170+
private static class RestGlobalExceptionHandler {
171+
172+
@ExceptionHandler
173+
Error handleException(Throwable exception) {
174+
return new Error( "global - " + exception.getClass().getSimpleName());
175+
}
176+
}
84177

178+
static class Person {
179+
180+
private final String name;
181+
182+
Person(String name) {
183+
this.name = name;
184+
}
185+
186+
public String getName() {
187+
return name;
188+
}
189+
}
190+
191+
static class Error {
192+
193+
private final String error;
194+
195+
Error(String error) {
196+
this.error = error;
197+
}
198+
199+
public String getError() {
200+
return error;
201+
}
85202
}
86203

87204
}

0 commit comments

Comments
 (0)