2014-11-24 69 views
0

我有这样的图层:如何在Spring Junit中创建会话

Spring Controller - >服务图层 - > Dao图层(JPA)。

我想编写服务和控制器的测试用例。在其他Junit将调用控制器,控制器将调用服务,服务层获取数据库信息等。

在这种情况下,我不想嘲笑,我只想写junit测试用例(我必须调用服务和服务必须从数据库中获得真实的数据)。

我只有一个问题,服务层get从会话的用户ID。我使用autowired注释获取会话。如何在测试用例中创建假会话?

PS我想模仿不适合我......因为我不惯于嘲笑我的服务,我想创建一个真正的DB数据控制器的实时调用...

+0

它是一个会话范围保存用户数据的bean吗? – BzH 2014-11-24 10:50:37

+0

你的服务层组件是_session作用域bean_吗? – 2014-11-26 18:56:09

+0

另外,你对使用Spring MVC测试框架感兴趣吗? – 2014-11-26 19:19:36

回答

2

我们可以模拟做。这里是代码示例。

private MockMvc mockMvc; 

     @Autowired 
     private FilterChainProxy springSecurityFilterChain; 

     @Autowired 
     private WebApplicationContext wac; 

     protected MockHttpSession session; 

     protected MockHttpServletRequest request; 

     @Before 
     public void setup() { 
      this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilters(this.springSecurityFilterChain).build(); 
     } 

     @Test 
     void test(){ 
     // I log in and then returns session 
     HttpSession session = mockMvc.perform(post("/j_spring_security_check").param("NAME", user).param("PASSWORD", pass)) 
        .andDo(print()).andExpect(status().isMovedTemporarily()).andReturn().getRequest().getSession(); 
     } 

我们也可以用这种方法做,你可以调用startSession()方法,并会出现“电流”回来了。

protected void startSession() { 
     session = new MockHttpSession(); 
    } 

    protected void endSession() { 
     session.clearAttributes(); 
     session = null; 
    } 

    // we can create request too, just simple way 
    protected void startRequest() { 
     request = new MockHttpServletRequest(); 
     request.setSession(session); 
     RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); 
    } 
2
+0

我不会嘲笑。因为然后我调用this.mockMvc.perform(我的控制器),模拟不会调用我的服务层。这是我的问题,m – grep 2014-11-24 11:11:13

+0

我的意思是这个问题,当我使用模拟,所以我不会嘲笑:http://stackoverflow.com/questions/26508628/how-to-call-springs-service-method-from-controller -junit – grep 2014-11-24 11:16:19

+0

如果您将用户标识作为会话中的一个属性进行存储,则也可以在'MockHttpSession'上设置该属性。然后,当你的代码使用这个对象时,它会返回你想要的任何值。 – Foxsly 2014-11-24 16:45:05

0

一种办法是注入用户ID(不是HttpSession)到使用规划环境地政司表达你的服务组件。要实现正确的运行时行为,您必须确保您的服务组件是AOP范围的代理。

查看Spring参考手册的"Testing request and session scoped beans"部分以获取更多信息。

问候,

山姆spring-test成分铅)

0

我写了下面的函数在使用mongo会话存储时创建“真实”会话。

private Session generateMongoHttpSession(final Role role, final Permission... permissions) { 
    final Set<GrantedAuthority> authorities = 
    role.getPermissions() 
     .stream() 
     .map(p -> new SimpleGrantedAuthority(p.toString())) 
     .collect(Collectors.toSet()); 

    Arrays.stream(permissions) 
    .forEach(p -> authorities.add(new SimpleGrantedAuthority(p.toString()))); 

    final UserDetails userDetails = 
    new org.springframework.security.core.userdetails.User(
     "test-user-name", "test-password", true, true, true, true, authorities); 

    final Authentication authentication = 
    new UsernamePasswordAuthenticationToken(
     userDetails, userDetails.getPassword(), userDetails.getAuthorities()); 

    final UsernamePasswordAuthenticationToken authenticationToken = 
    new UsernamePasswordAuthenticationToken(
      userDetails, authentication.getCredentials(), userDetails.getAuthorities()); 
    authenticationToken.setDetails(authentication.getDetails()); 

    final SecurityContextImpl context = new SecurityContextImpl(); 
    context.setAuthentication(authentication); 

    final MongoExpiringSession session = mongoOperationsSessionRepository.createSession(); 
    session.setAttribute("SPRING_SECURITY_CONTEXT", context); 
    session.setAttribute("sessionId", session.getId()); 
    mongoOperationsSessionRepository.save(session); 

    return session; 
}