2012-02-09 7 views
2

私はspring 3 mvc/securityフレームワークを使用しています。@RunWithを使用しないSpring単体テストの配線依存性

データを読み込むリポジトリへの参照を持つControllerクラスを作成しました。クラスには@Controller、アノテーションには@Repository、リポジトリには@Autowiredというアノテーションが付けられています。

しかし、私がユニットテストをしようとすると、autowiredインスタンスはnullポインタ例外をスローします。

ここで私はそれがautowiredなので、それはピックアップするためには春の文脈内にある必要があることを理解しています。しかし、私が@RunsWith()を使用すると、統合テストになると感じています。私は本当に統合テスト(@RunsWithを使用)とこのメソッドの単体テストを分けたいと思います。どのように私はこのnullポインタの例外を回避することができます上の任意のアイデア?ちょうど私のコントローラクラスのgetter/setterメソッドは大丈夫作成だろう?:

リポジトリクラス:

@Repository 
public class Repository{ 
.... 
} 

コントローラクラス:

@Controller 
public class Controller{ 
@Autowired 
private Repository repo; 
.... 
public String showView(){ 
    repo.doSomething(); 
} 

Testクラス:

通常
public ControllerTest { 
@Test 
public shouldDoTestOfShowView(){ 
} 
} 
+0

コントローラでゲッタ/セッタを作成するのがベストプラクティスですか? –

答えて

3

私は個人的にはどちらかのアプローチが細かいですが、むしろセッターをさらすよりも、@Simon's approachを使用する傾向があります。テストのためだけにセッターを追加するのはちょっと面倒です。

別の方法として、Spring's ReflectionTestUtils classを使用して、リフレクトを使用してフィールドに依存関係を直接突き刺すことができます。これにより、特殊なコンストラクタとセッタが不要になります。

public ControllerTest { 
    @Test 
    public shouldDoTestOfShowView() { 
     Controller controller = new Controller(); 
     Repository repository = new Repository(); 

     ReflectionTestUtils.setField(controller, "repo", repository); 
    } 
} 

それがまだ「統合テスト」を構成しているかどうかは、あなたの呼び出しです(私はそうではありません)。

+0

私はreflectionTestUtilsが私の最高の賭けかもしれないと思います。しかし、私の場合、私のレポはautowiredエンティティマネージャを持っているので、ネストされたリフレクションを実行する方法を理解する必要があります。 –

+3

ユニットテストをしている場合は、リポジトリをモックする必要があります。 –

0

私はテスト目的のためだけにsetterを提供しますが、コードを使用するユーザーが私は不適切に、おそらくあなたは反射を利用するアプローチを使いたいと思うでしょう。

過去に、ターゲットに設定しているターゲットオブジェクトとオブジェクトの2つの引数を取るユーティリティを作成しました。 setMeOnTargetは、そのフィールド(Iに割り当てることができる場合は、ここから何ができるか

public static void set(Object target, Object setMeOnTarget) { 
    // 
} 

は、Springのサポートオートワイヤリング注釈を探して、targetの分野にイントロスペクション(@Autowired@Resource@Inject、多分@Value)と見ていますused Class.isAssignableFrom(Class))。

少し虚弱かもしれません(春は突然これらの注釈をサポートしていません...そうは思わない...)が、私にとってはうまくいっています。

2

私は常に2つのコンストラクタを書きます。 1つはSpringの引数なしで、1つはユニットテストのすべての依存関係を持つ保護されたものです。

@Controller 
public class Controller{ 
@Autowired 
private Repository repo; 

public Controller() { 
    super(); 
} 

protected Controller(Repositoy repo) { 
    this(); 
    this.repo = repo; 
} 
+0

@Autowiredという単一のコンストラクタだけではないのはなぜですか?フィールドレベルのオートワイヤリングを使用する代わりに? –

+1

XML構成を使用する場合は、@Autowiredとともに1つのコンストラクタしか使用できません。 Javaベースの設定を使用する場合は、クラスをJavaでインスタンス化し、空のコンストラクタを使用すると便利です。 –

関連する問題