4

我想集成测试一个Spring控制器方法,它使用弹簧会话scoped bean注入到控制器。为了让我的测试通过,我必须能够访问我的会话bean以在我对这个控制器方法进行模拟调用之前设置一些值。 Issue是一个新的会话bean,在我进行调用时创建,而不是使用我从模拟应用程序上下文中提取的那个。我如何让我的控制器使用相同的UserSession bean?MockMVC集成测试控制器与会话scoped bean

这里是我的测试案例

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration("src/main/webapp") 
@ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml", 
     "file:src/main/webapp/WEB-INF/rest-servlet.xml", 
     "file:src/main/webapp/WEB-INF/servlet-context.xml"}) 
public class RoleControllerIntegrationTest { 

    @Autowired 
    private WebApplicationContext wac; 

    protected MockMvc mockMvc; 
    protected MockHttpSession mockSession; 

    @BeforeClass 
    public static void setupClass(){ 
     System.setProperty("runtime.environment","TEST"); 
     System.setProperty("com.example.UseSharedLocal","true"); 
     System.setProperty("com.example.OverridePath","src\\test\\resources\\properties"); 
     System.setProperty("JBHSECUREDIR","C:\\ProgramData\\JBHSecure"); 
    } 

    @Before 
    public void setup(){ 
     mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); 
     mockSession = new MockHttpSession(wac.getServletContext(), UUID.randomUUID().toString()); 
     mockSession.setAttribute("jbhSecurityUserId", "TESTUSER"); 
    } 

    @Test 
    public void testSaveUserRole() throws Exception { 

     UserSession userSession = wac.getBean(UserSession.class); 
     userSession.setUserType(UserType.EMPLOYEE); 
     userSession.setAuthorizationLevel(3); 

     Role saveRole = RoleBuilder.buildDefaultRole(); 
     Gson gson = new Gson(); 
     String json = gson.toJson(saveRole); 

     MvcResult result = this.mockMvc.perform(
       post("/role/save") 
         .contentType(MediaType.APPLICATION_JSON) 
         .content(json) 
         .session(mockSession)) 
       .andExpect(status().isOk()) 
       .andReturn(); 

     MockHttpServletResponse response = result.getResponse(); 

    } 

这里是我·需要测试

@Resource(name="userSession") 
    private UserSession userSession; 

    @RequestMapping(method = RequestMethod.POST, value = "/save") 
    public @ResponseBody ServiceResponse<Role> saveRole(@RequestBody Role role,HttpSession session){ 

     if(userSession.isEmployee() && userSession.getAuthorizationLevel() >= 3){ 
      try { 
       RoleDTO savedRole = roleService.saveRole(role,ComFunc.getUserId(session)); 
       CompanyDTO company = userSession.getCurrentCompany(); 

它不通过这条线,因为UserSession对象是不一样的 如果我的控制方法(userSession .isEmployee()& & userSession.getAuthorizationLevel()> = 3){

This i是我的用户会话bean的声明。

@Component("userSession") 
    @Scope(value="session",proxyMode= ScopedProxyMode.INTERFACES) 
    public class UserSessionImpl implements UserSession, Serializable { 

    private static final long serialVersionUID = 1L; 

两个controlle和豆使用组件扫描我的applicationContext.xml

<context:annotation-config /> 
    <!-- Activates various annotations to be detected in bean classes --> 
    <context:component-scan 
     base-package=" 
      com.example.app.externalusersecurity.bean, 
      com.example.app.externalusersecurity.service, 
      com.example.app.externalusersecurity.wsc"/> 
    <mvc:annotation-driven /> 

回答

0

添加下面的bean配置,还增加了一个会话的上下文为每个线程创建

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> 
    <property name="scopes"> 
     <map> 
      <entry key="session"> 
       <bean class="org.springframework.context.support.SimpleThreadScope"/> 
      </entry> 
     </map> 
    </property> 
</bean> 

的在Java的配置类中相当于下面的bean声明

@Bean 
    public CustomScopeConfigurer scopeConfigurer() { 
    CustomScopeConfigurer configurer = new CustomScopeConfigurer(); 
    Map<String, Object> workflowScope = new HashMap<String, Object>(); 
    workflowScope.put("session", new SimpleThreadScope()); 
    configurer.setScopes(workflowScope); 

    return configurer; 
    } 

有关详细信息,请参阅 http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-custom-using

1

使用的测试和生产不同Bean definition profiles为我工作 - 在这里是一个基于XML的设置就怎么看起来像:

<beans profile="production"> 
    <bean id="userSession" class="UserSessionImpl" scope="session" > 
     <aop:scoped-proxy/> 
    </bean> 
</beans> 

<beans profile="test"> 
    <bean id="userSession" class="UserSessionImpl" > 
    </bean> 
</beans> 

为使用测试配置文件你测试,将@ActiveProfiles添加到您的测试类中:

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration("src/main/webapp") 
@ContextConfiguration({"file:src/main/webapp/WEB-INF/applicationContext.xml", 
    "file:src/main/webapp/WEB-INF/rest-servlet.xml", 
    "file:src/main/webapp/WEB-INF/servlet-context.xml"}) 
@ActiveProfiles(profiles = {"test"}) 
public class RoleControllerIntegrationTest { 
[...]