Spring mvc 3.1 integration tests with session support

java, spring, spring-mvc, testing

Solution

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")));

Problem

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: ``` @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()); } } ``` My session is empty in every request, I don't know why. EDIT: The last assert is failing: `andExpect(status().isOk());`. It returns 403 instead of 200.

Original source

Related problems