在基于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 {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic void setup() {this.mockMvc = webAppContextSetup(this.wac).build();}@Testpublic 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