2017-10-07 12 views
1

私はSpring Boot 1.4.2を使用しています。私はSpring Bootで新しくなっています。ここで SpringBootTest模擬認証ユーザがカスタムユーザで動作しない

public static String getCurrentUserToken(){ 
    return ((AuthenticatedUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserId(); 
} 

は私のカスタムAuthenticatedUserさ: 私は、コントローラのためのアドバイスで におけるユーザログが、私は以下のように現在のuserIdを取得するための呼び出しを行ったときに、現在のユーザー情報を設定するための認証フィルタを持っています:

public class AuthenticatedUser implements Serializable { 

private final String userName; 
private final String userId; 
private final String sessionId; 

public AuthenticatedUser(String userName, String userId, String sessionId) { 
    super(); 
    this.userName = userName; 
    this.userId = userId; 
    this.sessionId = sessionId; 
} 

public String getUserName() { 
    return userName; 
} 

public String getUserId() { 
    return userId; 
} 

public String getSessionId() { 
    return sessionId; 
} 

}

すべてが正常に動作します。 しかし、フィルタは統合テストでは機能しません。私は現在のユーザーをモックする必要があります。 私はユーザーを模倣する方法をたくさん探しましたが、それらのどれも私を助けませんでした。私は最終的に私が望んでいたものに近い可能性があり、このガイドを発見:以下https://aggarwalarpit.wordpress.com/2017/05/17/mocking-spring-security-context-for-unit-testing/ はそのガイドライン以下の私のテストクラスである:私は数日を過ごした

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
AuthenticatedUser cannot be returned by getAuthentication() 
getAuthentication() should return Authentication 

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) 
public class PersonalLoanPreApprovalTest { 

@Before 
public void initDB() throws Exception { 
    MockitoAnnotations.initMocks(this); 
} 

@Test 
public void testRequestPersonalLoanPreApproval_Me() { 
    AuthenticatedUser applicationUser = new 
    AuthenticatedUser("[email protected]", "2d1b5ae3", "123"); 
    UsernamePasswordAuthenticationToken authentication = new ApiKeyAuthentication(applicationUser); 
    SecurityContext securityContext = mock(SecurityContext.class); 

    when(securityContext.getAuthentication()).thenReturn(authentication); 
    SecurityContextHolder.setContext(securityContext); 

    // error at this line 
    when(securityContext.getAuthentication().getPrincipal()) .thenReturn(applicationUser); 

    // The controller for this api has the advice to get the userId 
    MyResponse response = restTemplate.getForObject(url.toString(), MyResponse.class); 
} 
} 

私はこのエラーを得ましたこれは既に私が見つけた多くの提案を試みましたが、まだ失敗しました。私もエラーの原因となる行を削除しようとしましたが、エラーがなくなっても、私のコントローラのアドバイスで現在のユーザー情報を取得できませんでした。

どのような提案も高く評価されています。

UPDATE1:私の結果にコードを少し修正したかっただけです。私は今、テストクラス内のエラーを取り除くことができます

@Test 
public void testRequestPersonalLoanPreApproval_Me() { 
    AuthenticatedUser applicationUser = new AuthenticatedUser("[email protected]", "2d1b5ae3-cf04-44f5-9493-f0518cab4554", "123"); 
    Authentication authentication = Mockito.mock(Authentication.class); 
    SecurityContext securityContext = Mockito.mock(SecurityContext.class); 
    Mockito.when(securityContext.getAuthentication()).thenReturn(authentication); 
    SecurityContextHolder.setContext(securityContext); 
    Mockito.when(authentication.getPrincipal()).thenReturn(applicationUser);  

    // The controller for this api has the advice to get the userId 
    MyResponse response = restTemplate.getForObject(url.toString(), MyResponse.class); 
} 
} 

:@glitchの提案で

は、私は以下のように私の試験方法で認証し、ユーザーを欺くためにコードを変更しました。コードにデバッグしました。私がテストクラスに入っているときにsecurityContextに値があることを確認してください。私は、コントローラのアドバイス内のコードにジャンプするときには、以下の戻りをnullを取得:

SecurityContextHolder.getContext().getAuthentication().getPrincipal() 
+0

try: 'when(securityContext.getAuthentication())thenReturn((認証)認証); ' – mangotang

+0

あなたの提案に感謝します。私はそれを試して、まだ行に古いエラーがあります: '(securityContext.getAuthentication()。getPrincipal())。then return(applicationUser);'。私のために他の提案がありますか? – Sal

答えて

0

あり

@Test 
@WithMockUser(username = "myUser", roles = { "myAuthority" }) 
public void aTest(){ 
    // any usage of `Authentication` in this test invocation will get an instance with the user name "myUser" and a granted authority "myAuthority" 
    // ... 
} 

また、あなたのためにこれを行い春のテスト注釈(org.springframework.security.test.context.support.WithMockUser)...、 SpringのAuthenticationを嘲笑して、現在のアプローチを続けることができます。たとえば、あなたのテストケースには:次に

Authentication authentication = Mockito.mock(Authentication.class); 

このAuthenticationインスタンスを保存するためにSpringのSecurityContextHolderを伝える:

SecurityContext securityContext = Mockito.mock(SecurityContext.class); 
Mockito.when(securityContext.getAuthentication()).thenReturn(auth); 
SecurityContextHolder.setContext(securityContext); 

、あなたのコードは(おそらくユーザー名)何かを返すようにAuthenticationを必要とする場合、あなただけの模倣されたAuthenticationインスタンスにいくつかの期待値を通常の方法で設定する

Mockito.when(authentication.getName()).thenReturn("aName"); 

これは既に行っていることに非常に近いですが、間違ったタイプを嘲笑しただけです。

更新1:OPにこのアップデートに対応して

I now can get rid of the error in the testing class. I debugged into the code, see that the securityContext has value when I am in the testing class. But when I jump to the code inside the controller advice, the below get returns null:

SecurityContextHolder.getContext().getAuthentication().getPrincipal()

あなただけ例えば、嘲笑Authenticationに期待を設定する必要があります。以上により

UsernamePasswordAuthenticationToken principal = new UsernamePasswordAuthenticationToken("aUserName", "aPassword"); 
Mockito.when(authentication.getPrincipal()).thenReturn(principal); 

この行をコーディングする...

SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 

は... UsernamePasswordAuthenticationTokenを返します。

カスタムタイプ(ApiKeyAuthentication、私はそうだと思います)を使用したので、authentication.getPrincipal()にはUsernamePasswordAuthenticationTokenの代わりにそのタイプが返されます。

+0

あなたの提案に感謝@glitch。私の難しさは、私は 'ApiKeyAuthentication'であるカスタム認証を持っているということです。そのカスタム認証の中に、私はカスタムユーザ 'AuthenticatedUser'を持っています。さらに複雑なものを追加するために、私が取り戻したい情報は 'AuthenticatedUser'の' userId'です。私が取得する必要がある情報は、私の元の投稿の最初のコードセクションに掲載されています。私は仕事を継続し、すべてのカスタム認証のものは前に作成されたものです。他の提案があれば感謝します。 – Sal

関連する問題