3

私は以前に Spring DI を使用したことがあり、Spring を使用せずに Spring Bean クラスをテストできることが利点の 1 つとして認識されています (簡潔にするためにインポートは省略されています)。

public class Foo {
    private String field;

    public void setField(String field) { this.field = field; }
    public String getField() { return field; }
} 

public class TestFoo {
    @Test
    public void test_field_is_set() {
       Foo foo = new Foo();
       foo.setField("Bar");
       assertEquals("Bar", foo.getField());
    }
}

現在、私は JSR-330 を試しています。これは、セッターを明示的に記述しないことを意味します。

これまでのところ、Hk2 を使用しています。これは、純粋に、Jersey が Hk2 に関連付けられており、他の JSR-330 実装との共存が困難になっているという逸話があるためです。

public class Foo {
   @Inject 
   private String field;
}

@Inject アノテーションによってセッターが使用可能になるという魔法が起こることを半分期待していましたが、そうではありません。

Foo foo = new Foo();
foo.setField("Bar"); // method setField(String) is undefined for the type Foo
  • フレームワークを呼び出さずに、この種の注釈付きクラスを (便利に) テストするにはどうすればよいですか?
  • それができない場合、移植可能な方法でフレームワークを呼び出すにはどうすればよいですか (つまり、テスト コードを Hk2、Guice などに緊密に結合せずに)。
  • それができない場合、この方法で注釈が付けられたクラスをテストするための典型的でクリーンな方法は何ですか?
4

4 に答える 4

2

最も簡単なのは、フィールドをパッケージ プライベート (プライベートではなく) にしてから、テストで直接設定することです。(これは、テストが同じパッケージにある場合に機能します)

public class Foo {
   @Inject 
   String field;
}



Foo foo = new Foo();
foo.field = "bar";

これにはリフレクションを回避できるという利点があるため、リファクタリングに対して安全です。

于 2013-11-07T08:32:04.730 に答える
1

プライベート/保護されたフィールド アクセスに依存するフレームワークはそれほど珍しいものではないことがわかりました。Hibernate、JPA、Spring 自体を含むいくつかの JSR-330 実装はすべてそれを行います。

Spring の spring-test パッケージは、これらのフィールドにアクセスするための静的メソッドを含むReflectionTestUtilsクラスを提供します。

これを使用すると、質問のクラスを次のようにテストできます。

import static org.springframework.test.util.ReflectionTestUtils.*;

...

@Test
public void testUsingSpringReflectionTestUtils() {
    Foo foo = new Foo();
    setField(foo, "field", "Bar");
    assertEquals("Bar", foo.getField());
}

これが機能するには、テスト クラスパスに spring-test と spring-core が必要ですが、本番コードの Spring への依存関係は追加されません。

(同じ原理の別の実装についてのコメントは歓迎します。Spring の実装が優れていることを考えると、それがどんなに単純であっても、独自に開発する価値はないと思います。)

于 2013-11-05T16:34:24.793 に答える
1

「針」を試してみてください: http://needle.spree.de/overview

needle は、コンテナーの動作のみをシミュレートする DI テスト フレームワークであり、単体テストを非常にシンプルにします。

于 2013-11-05T23:28:13.423 に答える
1

あなたが言及したフィールド注入アプローチは、実際には典型的な Spring スタイルです。多くのプログラマーは、プライベートに挿入されたフィールドのセッターをまったく作成しません。Spring (@Autowiredまたはを使用@Inject) および JSR-330 コンテナーは通常、セッターではなく直接フィールド リフレクションを使用してフィールドを注入します。

このため、DI フレームワークを使用したくない場合は、必要なリフレクション コードを自分で単体テストに書き込むことができますが、これはテストの依存関係を回避するためだけにやり過ぎのように思えます。結局のところ、使用のポイントは@Inject、インターフェースにコーディングしていることであり、JVM を使用してインターフェースへの結合を回避しないということではありません。

この種のクラスをテストするための通常のアプローチは、好みのコンテナーのテスト コンテキストをセットアップし、そのコンテキストで単体テストを実行することです。Spring を使用している場合は、applicationContext-test.xmlファイルまたはTestConfigクラスをsrc/test/ディレクトリ (または同等のもの) に配置し、Guice を使用している場合は、モックまたはテスト データセットを接続するモジュールを作成します。

于 2013-11-05T13:16:04.710 に答える