2017-01-10 7 views
0

私はSpringフレームワークを使用し、注入されたサービスと対話する以外に、の新しいオブジェクトを静的メソッドを使用して取得し、そのように:ニュースの新しいオブジェクトと静的メソッドを使用するテストメソッド

私はそれをテストするにはどうすればよいですか(メソッドが呼び出され、正しい引数がそれらに渡されることを確認します)? UsernamePasswordAuthenticationTokenSecurityContextHolderを単純に嘲笑することはできません。私は両方のもののための工場を作ることができました、そしてそれは問題を解決するでしょうが、これほどシンプルな何かのために巨大な過度の気分のように感じます。さらに、私は工場をテストする必要があります。別の方法がありますか?

答えて

0

私はあなたに2つの答えを持っています。私は前に両方をしました。

現在、使用しているアプローチは、Springセキュリティフィルタチェーンなしでコントローラ/サービスレベルでテストすることです。発見したように、これはあなた自身がThreadLocal SecurityContextを管理する必要があることを意味します。 通常、JUnitテストの前に何かしたいときは、@Before注釈付きメソッドの中に入れます。

@Before 
public void before() { 
    UserDetails userDetails = userDetailsService.loadUserByUsername(name); 

    Authentication token = new UsernamePasswordAuthenticationToken(userDetails, 
      password, userDetails.getAuthorities()); 

    Authentication authentication = authenticationManager.authenticate(token); 

    SecurityContextHolder.getContext().setAuthentication(authentication); 
} 

と我々は

@After 
public void test() { 
    SecurityContextHolder.getContext().setAuthentication(null); 
} 

このアプローチは動作しますが、それは二つの主要な欠点を持っている@After使用クリーンアップ。それはSpringのフィルタチェーンをチェックせず、コントローラのリクエストルーティングをチェックしません - このようなテストを書くのをやめました。ウェブサーバを使わずに完全なウェブスタックをテストする方法がはるかに優れているからです。

新しい友達MockMvcにようこそ! Web層全体をテストするSpring Testを設定することができます。これにより、資格が間違っている場合を除いて、ユーザーがログインにリダイレクトされたことを確認できます。また、無効なJSONを送信すると正しい400 Bad Inputが返されることを確認します。

まず、MockMvcのマニュアルを読むことをお勧めします。あなたは基本的に精通しているいったんhere

+0

私はお詫びしますが、私はあなたが私の質問を誤解していると思います(私は十分ではないかもしれません)。これは私のメソッド内にあるコードで、このコード(私の質問にあるコード)をテストするテストを書く必要があります。言い換えれば、私はこのコードが適切な認証を実行することを確認するテストを書く必要がありますが、実際には必ずしも認証である必要はありません。ここで重要なのは、コード内の新しい演算子と静的オブジェクトの存在です。 – user5080246

+0

私はあなたの質問に間違いがありますが、あなたが本当に奇妙なユースケースを持っているか、あなたが間違った方法でSpringセキュリティを使用しています。あなたは '' '' SecurityContextHolder.getContext()。setAuthentication() '' 'を呼び出すように、Springが呼び出す' '' AuthenticationProvider''(そしておそらく '' 'UserDetailsS​​ervice''')を実装することになっています。フィルタチェーンが完了したとき。 –

+0

あなたは正しいです。私は手動で私のコントローラ(パスワードでユーザ名を受け取った)で認証しようとしています。 OpenId認証は私のためには機能しません。私はフォームを持っていないので、フォームのログインを使用できません(これは純粋にRESTベースのものです)、ブラウザには資格情報の入力フォームが表示されないのでBasic認証を使用できません(認証失敗時)。だから私は自分の認証を実装する必要があります。私はおそらくAuthProviderを使うべきですが、私はそれを使う方法を理解していません。私はドキュメンテーションの理解から、AuthenticationManagerのように機能します。あなたは正しい方向に私を振りかけることができますか? – user5080246

1

を説明するように、あなたはSpringSecurityのSecurityMockMvcConfigurers.springSecurity()を適用することができます@KlausGroenbaekの答えは、JUnitのフレームワークで行わをテストモジュールのテスト受け入れを説明しています。これは重要なテストタイプであり、間違いなくあなたがやりたいことです。

ただし、ユニットテストではありません。あなたのユニットが通信するものがモックまたはデータ転送オブジェクト(DTO)(あるいは「失敗する単純すぎる」)なければならないことを意味し、分離であなたコードの小さな部品の

ユニットテストのテストの振る舞い、 。


温家宝私はあなたが静的メソッド呼び出しSecurityContextHolder.getContext()をrefacorのいずれか、それは結果(コンテキスト?)のget パッケージプライベートゲッターを介して、またはあなたのクラスに注入する必要があり、あなたのコードにこれを採用してみてくださいあまりにも。

次に、Mockitoやその他のモッキングフレームワークを使用して、contextuserDetailsServiceauthManagerの3つの依存関係をモックできます。 パッケージの場合は、ゲッターのMockito.spy()と一緒にMockito.doReturn(cotextMock).when(myClass.getContext())(または選択した模擬フレームワークと同等)を使用します。
私はスパイオブジェクトとのフォームを好む私はこのフォームを好むwhen().thenReturn()フォームはしないでください。

UsernamePasswordAuthenticationTokenのインスタンス化は、メソッド呼び出しauthenticationManager.authenticate(token)のパラメータを取得することによって間接的に確認できます。 MockitoにはArgumentCaptor utilクラスがあります。

関連する問題