복붙노트

[SPRING] 세션 지원을 사용하는 Spring mvc 3.1 통합 테스트

SPRING

세션 지원을 사용하는 Spring mvc 3.1 통합 테스트

3.1 버전의 새로운 스프링 테스트를 사용하여 통합 테스트를 실행합니다. 그것은 잘 작동하지만 세션을 작동시킬 수는 없습니다. 내 코드 :

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("src/main/webapp")
@ContextConfiguration({"classpath:applicationContext-dataSource.xml",
      "classpath:applicationContext.xml",
      "classpath:applicationContext-security-roles.xml",
      "classpath:applicationContext-security-web.xml",
      "classpath:applicationContext-web.xml"})
public class SpringTestBase {

    @Autowired
    private WebApplicationContext wac;
    @Autowired
    private FilterChainProxy springSecurityFilterChain;
    @Autowired
    private SessionFactory sessionFactory;

    protected MockMvc mock;
    protected MockHttpSession mockSession;

    @Before
    public void setUp() throws Exception {
       initDataSources("dataSource.properties");

       mock = MockMvcBuilders.webAppContextSetup(wac).addFilters(springSecurityFilterChain).build();
       mockSession = new MockHttpSession(wac.getServletContext(), UUID.randomUUID().toString());
    }

    @Test
    public void testLogin() throws Exception {
        // this controller sets a variable in the session
        mock.perform(get("/")
            .session(mockSession))
            .andExpect(model().attributeExists("csrf"));

        // I set another variable here just to be sure
        mockSession.setAttribute(CSRFHandlerInterceptor.CSRF, csrf);

        // this call returns 403 instead of 200 because the session is empty...
        mock.perform(post("/setup/language")
            .session(mockSession)
            .param(CSRFHandlerInterceptor.CSRF, csrf)
            .param("language", "de"))
            .andExpect(status().isOk());
    }
}

모든 요청에서 내 세션이 비어 있습니다. 이유를 모르겠습니다.

편집 : 마지막 assert 실패합니다 : andExpect (status (). isOk ()) ;.. 200 대신에 403을 반환합니다.

해결법

  1. ==============================

    1.나는 다소 우회적 인 방식으로 이것을 해냈다. 내가 한 일은 Spring Security가 세션에서 생성 된 관련 Security 속성으로 세션을 생성 한 다음이 세션을 다음과 같이 포착하게하는 것입니다.

    나는 다소 우회적 인 방식으로 이것을 해냈다. 내가 한 일은 Spring Security가 세션에서 생성 된 관련 Security 속성으로 세션을 생성 한 다음이 세션을 다음과 같이 포착하게하는 것입니다.

        this.mockMvc.perform(post("/j_spring_security_check")
                .param("j_username", "fred")
                .param("j_password", "fredspassword"))
                .andExpect(status().isMovedTemporarily())
                .andDo(new ResultHandler() {
                    @Override
                    public void handle(MvcResult result) throws Exception {
                        sessionHolder.setSession(new SessionWrapper(result.getRequest().getSession()));
                    }
                });
    

    SessionHolder는 세션을 보유하기위한 나의 커스텀 클래스입니다 :

    private static final class SessionHolder{
        private SessionWrapper session;
    
    
        public SessionWrapper getSession() {
            return session;
        }
    
        public void setSession(SessionWrapper session) {
            this.session = session;
        }
    }
    

    SessionWrapper는 세션 메소드가 MockHttpSession을 필요로하기 때문에 MockHttpSession으로부터 확장되는 또 다른 클래스이다.

    private static class SessionWrapper extends MockHttpSession{
        private final HttpSession httpSession;
    
        public SessionWrapper(HttpSession httpSession){
            this.httpSession = httpSession;
        }
    
        @Override
        public Object getAttribute(String name) {
            return this.httpSession.getAttribute(name);
        }
    
    }
    

    이 세트를 사용하면 sessionHolder에서 세션을 가져 와서 다음 메소드를 실행할 수 있습니다 (예 : 예 : 나의 경우에는:

    mockMvc.perform(get("/membersjson/1").contentType(MediaType.APPLICATION_JSON).session(sessionHolder.getSession()))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("OneUpdated")));
    
  2. ==============================

    2.업데이트 된 답변 :

    업데이트 된 답변 :

    새로운 메소드 "sessionAttrs"가 빌더에 추가 된 것 같습니다 (세션 속성을 사용하여 mvc 컨트롤러 테스트 참조)

    Map<String, Object> sessionAttrs = new HashMap<>();
    sessionAttrs.put("sessionAttrName", "sessionAttrValue");
    
    mockMvc.perform(MockMvcRequestBuilders.get("/uri").sessionAttrs(sessionAttrs))
          .andDo(print())
          .andExpect(MockMvcResultMatchers.status().isOk());
    

    이전 답 :

    지원하는 클래스를 사용하지 않고 동일한 결과를 얻는 더 간단한 해결책은 여기 있습니다.이 코드는 제 코드입니다 (Biju Kunjummen이 대답했을 때 이미 사용 가능한 방법인지는 모르겠습니다).

    
            HttpSession session = mockMvc.perform(post("/login-process").param("j_username", "user1").param("j_password", "user1"))
                .andExpect(status().is(HttpStatus.FOUND.value()))
                .andExpect(redirectedUrl("/"))
                .andReturn()
                .getRequest()
                .getSession();              
    
            Assert.assertNotNull(session);
    
            mockMvc.perform(get("/").session((MockHttpSession)session).locale(Locale.ENGLISH))
                .andDo(print())
                .andExpect(status().isOk()) 
                .andExpect(view().name("logged_in"));
    
    
  3. from https://stackoverflow.com/questions/13687055/spring-mvc-3-1-integration-tests-with-session-support by cc-by-sa and MIT license