在基于Spring的Web应用程序中,bean的作用域可以是用户“会话”。 从本质上讲,这意味着对会话范围的Bean的状态更改仅在用户会话范围内可见。
此项的目的是简单地突出显示Spring Test MVC提供的一种方法,以测试将会话范围的bean作为依赖项的组件。
考虑一下UserPreferences类的Spring参考文档中的示例,其中包含用户的timeZoneId:
@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class UserPreferences {
private String timeZoneId="default";
public String getTimeZoneId() {
return timeZoneId;
}
public void setTimeZoneId(String timeZoneId) {
this.timeZoneId = timeZoneId;
}
}
在这里,范围被标记为“会话”,并且proxyMode被明确指定为TARGET_CLASS,以指示Spring创建CGLIB代理(因为UserPreferences不实现任何其他接口)。
现在考虑使用此会话范围的bean作为依赖项的控制器:
@Controller
public class HomeController {
@Autowired private UserPreferences userPreferences;
@RequestMapping(value="/setuserprefs")
public String setUserPrefs(@RequestParam("timeZoneId") String timeZoneId, Model model) {
userPreferences.setTimeZoneId(timeZoneId);
model.addAttribute("timeZone", userPreferences.getTimeZoneId());
return "preferences";
}
@RequestMapping(value="/gotopage")
public String goToPage(@RequestParam("page") String page, Model model) {
model.addAttribute("timeZone", userPreferences.getTimeZoneId());
return page;
}
}
这里有两种控制器方法,在第一种方法中,设置用户偏好,在第二种方法中,读取用户偏好。 如果会话作用域的bean运行正常,则在用户会话中对“ / setuserprefs”的调用应在UserPreferences bean中设置timeZoneId首选项,而在同一会话中的另一个调用“ / gotopage”应成功检索先前设置的首选项。
使用现在与Spring-test模块打包在一起的Spring MVC测试支持,对此进行测试很简单。
测试看起来像这样:
首先使用Spring Java Configuration进行测试的bean定义:
@Configuration
@EnableWebMvc
@ComponentScan({"scope.model","scope.services", "scope.web"})
public class ScopeConfiguration {}
和测试:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=ScopeConfiguration.class)
@WebAppConfiguration
public class ScopeConfigurationTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac).build();
}
@Test
public void testSessionScope() throws Exception {
MockHttpSession mocksession = new MockHttpSession();
this.mockMvc.perform(
get("/setuserprefs?timeZoneId={timeZoneId}", "US/Pacific")
.session(mocksession))
.andExpect(model().attribute("timeZone", "US/Pacific"));
this.mockMvc.perform(
get("/gotopage?page={page}", "home")
.session(mocksession))
.andExpect(model().attribute("timeZone", "US/Pacific"));
this.mockMvc.perform(
get("/gotopage?page={page}", "home")
.session(new MockHttpSession()))
.andExpect(model().attribute("timeZone", "default"));
}
}
在测试中,首先创建一个MockHttpSession来模拟用户会话。 随后的两个请求是在此模拟会话的上下文中发出的,因此期望在测试中声明的控制器中可以看到相同的UserPreferences bean。 在第三个请求中,创建了一个新会话,这次是在控制器中看到另一个UserPreferences bean,这是通过查找其他属性来断言的。
这演示了使用Spring测试MVC支持来测试会话范围的bean的干净方法。
翻译自: https://www.javacodegeeks.com/2013/06/testing-spring-session-scope.html