Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring mvc 3.1 integration tests with session support

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.

like image 227
islon Avatar asked Dec 03 '12 16:12

islon


1 Answers

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

like image 130
Emanuele Ivaldi Avatar answered Oct 12 '22 12:10

Emanuele Ivaldi