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.