2017-12-26 14 views
2

コントローラユニットテストを行うには2つの方法を試しました。SecurityContextHolderは、junitテストで「login」ユーザを「anonymous」として正しく返します

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()は、正しい​​を含むはずですが、「anonymous」を返します。 M2の場合:春のUser pojoが返されます。なぜなら私はcustomizedUserDetailsServiceというbeanを生成されたカスタマイズされたユーザーpojoに使用しなければならないからです。これは春のバグですか?私はさらに見つけました:M1では、SecurityContextHolder setContextが2回呼び出され、1番目のコンテキスト引数が正しく、2番目のコンテキスト引数が間違っている間に自分のユーザーpojoが含まれていました。

SOLUTIONは、GHの男は、私は統合テストと模擬テストを混同することをM1にコメント、および@WithUserDetailsは、模擬テストのためです。だから私は@WithUserDetailsMockMvc(M1とM2の組み合わせ)を使用し、その結果は、それが私の目標を達成することを示しています

  1. ユーザログイン

    は、customizedUserDetailsS​​ervice豆を通過しました。
  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では何かを設定する必要があります。

そのためのいくつかの方法がありますが、あなたがMokitoを使用してSecurityContextHolderためSecurityContextオブジェクトを設定することがあります。

`@WithUserDetails(値= "トム"、userDetailsS​​erviceBeanName = "customizedUserDetailsS​​erviceは")`を返すべきではありません
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

匿名ユーザー。 2番目のメソッドmockXXXは、必要なpojoを返すcustomizedUserDetailsS​​ervice beanを通過しません。 – Tiina

+0

'@ WithUserDetails'を使用する必要はありません。' mvc.perform(post(uri).... 'のように設定することができます。 – jfun

+0

mvc.withメソッドは、カスタマイズされたユーザーBeanではなくSpringユーザーを誘導します。その豆が必要です。 – Tiina

関連する問題