Introduce regression tests for prototype/request-scoped @ControllerAdvice
See gh-24157
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.test.web.servlet.samples.spr;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -25,6 +26,7 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
@@ -33,6 +35,7 @@ import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.annotation.RequestScope;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
@@ -64,21 +67,53 @@ public class ControllerAdviceIntegrationTests {
|
||||
@Before
|
||||
public void setUpMockMvc() {
|
||||
this.mockMvc = webAppContextSetup(wac).build();
|
||||
resetCounters();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void controllerAdviceIsAppliedOnlyOnce() throws Exception {
|
||||
assertEquals(0, SingletonControllerAdvice.counter.get());
|
||||
assertEquals(0, RequestScopedControllerAdvice.counter.get());
|
||||
|
||||
this.mockMvc.perform(get("/test"))//
|
||||
this.mockMvc.perform(get("/test").param("requestParam", "foo"))//
|
||||
.andExpect(status().isOk())//
|
||||
.andExpect(forwardedUrl("singleton:1;request-scoped:1"));
|
||||
.andExpect(forwardedUrl("singleton:1;prototype:1;request-scoped:1;requestParam:foo"));
|
||||
|
||||
assertEquals(1, SingletonControllerAdvice.counter.get());
|
||||
assertEquals(1, RequestScopedControllerAdvice.counter.get());
|
||||
assertEquals(1, SingletonControllerAdvice.invocationCount.get());
|
||||
assertEquals(1, PrototypeControllerAdvice.invocationCount.get());
|
||||
assertEquals(1, RequestScopedControllerAdvice.invocationCount.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prototypeAndRequestScopedControllerAdviceBeansAreNotCached() throws Exception {
|
||||
this.mockMvc.perform(get("/test").param("requestParam", "foo"))//
|
||||
.andExpect(status().isOk())//
|
||||
.andExpect(forwardedUrl("singleton:1;prototype:1;request-scoped:1;requestParam:foo"));
|
||||
|
||||
// singleton @ControllerAdvice beans should not be instantiated again.
|
||||
assertEquals(0, SingletonControllerAdvice.instanceCount.get());
|
||||
// prototype and request-scoped @ControllerAdvice beans should be instantiated once per request.
|
||||
assertEquals(1, PrototypeControllerAdvice.instanceCount.get());
|
||||
assertEquals(1, RequestScopedControllerAdvice.instanceCount.get());
|
||||
|
||||
this.mockMvc.perform(get("/test").param("requestParam", "bar"))//
|
||||
.andExpect(status().isOk())//
|
||||
.andExpect(forwardedUrl("singleton:2;prototype:2;request-scoped:2;requestParam:bar"));
|
||||
|
||||
// singleton @ControllerAdvice beans should not be instantiated again.
|
||||
assertEquals(0, SingletonControllerAdvice.instanceCount.get());
|
||||
// prototype and request-scoped @ControllerAdvice beans should be instantiated once per request.
|
||||
assertEquals(2, PrototypeControllerAdvice.instanceCount.get());
|
||||
assertEquals(2, RequestScopedControllerAdvice.instanceCount.get());
|
||||
}
|
||||
|
||||
private static void resetCounters() {
|
||||
SingletonControllerAdvice.invocationCount.set(0);
|
||||
SingletonControllerAdvice.instanceCount.set(0);
|
||||
PrototypeControllerAdvice.invocationCount.set(0);
|
||||
PrototypeControllerAdvice.instanceCount.set(0);
|
||||
RequestScopedControllerAdvice.invocationCount.set(0);
|
||||
RequestScopedControllerAdvice.instanceCount.set(0);
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
static class Config {
|
||||
@@ -93,6 +128,12 @@ public class ControllerAdviceIntegrationTests {
|
||||
return new SingletonControllerAdvice();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope("prototype")
|
||||
PrototypeControllerAdvice prototypeControllerAdvice() {
|
||||
return new PrototypeControllerAdvice();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@RequestScope
|
||||
RequestScopedControllerAdvice requestScopedControllerAdvice() {
|
||||
@@ -103,22 +144,49 @@ public class ControllerAdviceIntegrationTests {
|
||||
@ControllerAdvice
|
||||
static class SingletonControllerAdvice {
|
||||
|
||||
static final AtomicInteger counter = new AtomicInteger();
|
||||
static final AtomicInteger instanceCount = new AtomicInteger();
|
||||
static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
|
||||
{
|
||||
instanceCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@ModelAttribute
|
||||
void initModel(Model model) {
|
||||
model.addAttribute("singleton", counter.incrementAndGet());
|
||||
model.addAttribute("singleton", invocationCount.incrementAndGet());
|
||||
}
|
||||
}
|
||||
|
||||
@ControllerAdvice
|
||||
static class PrototypeControllerAdvice {
|
||||
|
||||
static final AtomicInteger instanceCount = new AtomicInteger();
|
||||
static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
|
||||
{
|
||||
instanceCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@ModelAttribute
|
||||
void initModel(Model model) {
|
||||
model.addAttribute("prototype", invocationCount.incrementAndGet());
|
||||
}
|
||||
}
|
||||
|
||||
@ControllerAdvice
|
||||
static class RequestScopedControllerAdvice {
|
||||
|
||||
static final AtomicInteger counter = new AtomicInteger();
|
||||
static final AtomicInteger instanceCount = new AtomicInteger();
|
||||
static final AtomicInteger invocationCount = new AtomicInteger();
|
||||
|
||||
{
|
||||
instanceCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@ModelAttribute
|
||||
void initModel(Model model) {
|
||||
model.addAttribute("request-scoped", counter.incrementAndGet());
|
||||
void initModel(@RequestParam String requestParam, Model model) {
|
||||
model.addAttribute("requestParam", requestParam);
|
||||
model.addAttribute("request-scoped", invocationCount.incrementAndGet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,8 +195,11 @@ public class ControllerAdviceIntegrationTests {
|
||||
|
||||
@GetMapping("/test")
|
||||
String get(Model model) {
|
||||
return "singleton:" + model.asMap().get("singleton") + ";request-scoped:"
|
||||
+ model.asMap().get("request-scoped");
|
||||
Map<String, Object> map = model.asMap();
|
||||
return "singleton:" + map.get("singleton") +
|
||||
";prototype:" + map.get("prototype") +
|
||||
";request-scoped:" + map.get("request-scoped") +
|
||||
";requestParam:" + map.get("requestParam");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user