2017-12-26 4 views
2

컨트롤러 유닛 테스트를 수행하는 두 가지 방법을 시도했습니다.SecurityContextHolder가 junit 테스트에서 "익명"으로 로그인 사용자를 올바르게 반환합니다.

M1 :

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class WorkOrderControllerTest { 
    @Autowired 
    private TestRestTemplate testRestTemplate; 

    @Test 
    @WithUserDetails(value="Tom", userDetailsServiceBeanName = "customizedUserDetailsService") 
    public void testGetworkList() { 
     URI uri = URI.create("/foo"); 
     ResponseEntity exchange = testRestTemplate.getForEntity(uri, String.class); 
    } 
} 

M2 :

@Test 
public void testGetworkList() throws Exception { 

    List<GrantedAuthority> list = ...; 
    String uri = "/foo"; 

    ResultActions perform = mvc.perform(post(uri).with(csrf().asHeader()).with(user("Tom").roles("CP").authorities(list))); 
} 

@Before 
public void setup() { 
    mvc = MockMvcBuilders.webAppContextSetup(context) 
     .apply(SecurityMockMvcConfigurers.springSecurity()) 
     .build(); 
} 

둘 다 올바르게 로그인 (봄 보안 달리 모든 요청은 차단) 후, 제어부 방법을 수행 들어간다. M1의 경우 컨트롤러 뒤에있는 문 : SecurityContextHolder.getContext().getAuthentication()은 올바른 SecurityUser을 포함해야하며 "익명"을 반환합니다. M2의 경우 : 봄 사용자 pojo가 반환됩니다. 생성 된 사용자 정의 된 사용자 pojo에 대해 customizedUserDetailsService bean을 사용해야하기 때문에. 이것은 스프링 버그입니까? 더 많은 것을 발견했습니다 : M1에서 SecurityContextHolder setContext가 두 번 호출되고 첫 번째 컨텍스트 인수가 정확하고 두 번째 컨텍스트 인수가 잘못된 반면 내 자신의 사용자 pojo가 포함되어 있으며 이것이 "익명"의 원인이라고 생각합니다.

솔루션

GH에 사람이 내가 통합 테스트 및 모의 테스트를 혼합하는 M1에 댓글을, 그리고 @WithUserDetails 모의 테스트입니다. 그래서 @WithUserDetailsMockMvc (M1 및 M2의 조합)를 사용하고, 결과는 내 목표를 달성하는 것을 보여

  1. 사용자 로그인

    는 customizedUserDetailsService 콩을 통과.
  2. SecurityContextHolder는 로그인 사용자를 반환합니다.

코드 :

@Test 
@WithUserDetails(value="Tom", userDetailsServiceBeanName = "customizedUserDetailsService") 
public void testGetworkList() { 
    String uri = ...; 
    ResultActions result = mvc.perform(post(uri).with(csrf())); 
} 

답변

0

없음, 그것은 버그가 아니다; 즉, SecurityContextHolder싱글 콩이지만 JUnit을 시험에서이 맞습니다 스레드 범위하지 세션 범위을. JUnit으로 뭔가를 설정해야합니다. `리턴해서는 안됩니다 (userDetailsServiceBeanName는 = "customizedUserDetailsService는"값 = "톰")

Authentication authentication = Mockito.mock(Authentication.class); 
SecurityContext securityContext = Mockito.mock(SecurityContext.class); 
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication); 
SecurityContextHolder.setContext(securityContext); 
//Now you can access the real user loggedin 
+0

'@WithUserDetails :

은 그것을 위해, 당신은 Mokito를 사용할 수 있으며, SecurityContextHolder에 대한 SecurityContext 객체를 설정 몇 가지 방법이 있습니다 익명 사용자. 두 번째 방법 인 mockXXX는 customized_serDetailsService 빈을 지나치지 않고 필요한 pojo를 반환합니다. – Tiina

+0

그러면'@ WithUserDetails'를 사용할 필요가 없으므로'mvc.perform (post (uri) .... '를 사용하여 설정할 수 있습니다. – jfun

+0

mvc.with 메소드는 사용자 정의 된 사용자 bean이 아닌 Spring User를 유도합니다. 그 콩이 필요합니다. – Tiina