2012-12-03 35 views
15

Tôi đang sử dụng spring-test mới trong phiên bản 3.1 để chạy thử nghiệm tích hợp. Nó hoạt động thực sự tốt nhưng tôi không thể làm cho phiên làm việc. Mã của tôi:Kiểm tra tích hợp mvc mùa xuân 3.1 với hỗ trợ phiên

@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()); 
    } 
} 

Phiên của tôi trống trong mọi yêu cầu, tôi không biết tại sao.

EDIT: Xác nhận cuối cùng bị lỗi: andExpect(status().isOk());. Nó trả về 403 thay vì 200.

+0

Xác nhận nào bị lỗi? –

+0

Điều cuối cùng: 'andExpect (status(). IsOk());' bởi vì tôi kiểm tra phiên cho một biến cần được đặt, nhưng phiên đó trống nên nó sẽ trả về bị cấm. – islon

+0

Xem thêm [Cách đăng nhập người dùng với mùa xuân 3.2 thử nghiệm mvc mới] (http://stackoverflow.com/questions/14308341/how-to-login-a-user-with-spring-3-2-new-mvc thử nghiệm). – Arjan

Trả lời

9

Tôi đã làm điều này theo cách hơi xoay vòng - hoạt động. Những gì tôi đã làm là để cho mùa xuân-Security tạo một phiên làm việc với các thuộc tính bảo mật có liên quan dân cư trong phiên và sau đó lấy phiên theo cách này:

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 là lớp tùy chỉnh của tôi, chỉ để giữ phiên:

private static final class SessionHolder{ 
    private SessionWrapper session; 


    public SessionWrapper getSession() { 
     return session; 
    } 

    public void setSession(SessionWrapper session) { 
     this.session = session; 
    } 
} 

và SessionWrapper là một lớp kéo dài từ MockHttpSession, chỉ vì phương pháp phiên đòi hỏi 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); 
    } 

} 

với những s và, bây giờ bạn có thể chỉ cần lấy phiên từ sessionHolder và thực thi các phương thức tiếp theo, ví dụ. trong trường hợp của tôi:

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

Cảm ơn, nó hoạt động! – islon

21

CẬP NHẬT ĐÁP:

Có vẻ như một phương pháp mới "sessionAttrs" đã được thêm vào xây dựng (xem 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 ĐÁP:

đây là một giải pháp đơn giản để đạt được cùng một kết quả mà không cần sử dụng các lớp hỗ trợ, đây là một đoạn mã của tôi (Tôi không biết nếu các phương thức này đã có sẵn khi B iju Kunjummen đã trả lời):


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

Điều này chắc chắn sẽ là câu trả lời được chấp nhận! Câu trả lời được chấp nhận hiện tại là một hack rất bẩn để đạt được điều này. –

+0

nó thực sự là giải pháp tốt hơn http://stackoverflow.com/a/26341909/2674303 – gstackoverflow

+0

Tôi đang gặp sự cố khi triển khai giải pháp này. Im nhận ngoại lệ sau đây 'NestedServletException: Yêu cầu xử lý không thành công; ngoại lệ lồng nhau là java.lang.ArrayIndexOutOfBoundsException: -1'. Bất kỳ ý tưởng gì có thể gây ra nó? – JackB

Các vấn đề liên quan