Spring mvc 3.1 integration tests with session support

前端 未结 2 2042

I\'m using the new spring-test in the 3.1 version to run integration tests. It works really well but I can\'t make the session to work. My code:



        
相关标签:
2条回答
  • 2020-12-13 11:15

    UPDATED ANSWER:

    It seems a new method "sessionAttrs" has been added to the builder (see mvc controller test with session attribute)

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

    OLD ANSWER:

    here is a simpler solution to achieve the same result without using supporting classes, this is a snippet of my code (I don't know if these methods had been already available when Biju Kunjummen answered):

    
            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"));
    
    
    0 讨论(0)
  • 2020-12-13 11:20

    I have done this in a somewhat roundabout manner - works though. What I did was to let Spring-Security create a session with the relevant Security attributes populated in the session and then grab that session this way:

        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 is my custom class, just to hold the session:

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

    and SessionWrapper is another class extending from MockHttpSession, just because the session method requires 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);
        }
    
    }
    

    With these set, now you can simply take the session from the sessionHolder and execute subsequent methods, for eg. in my case:

    mockMvc.perform(get("/membersjson/1").contentType(MediaType.APPLICATION_JSON).session(sessionHolder.getSession()))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("OneUpdated")));
    
    0 讨论(0)
提交回复
热议问题