5

私は単純なPOJOを持っています:

public class MyPOJO {
    @Inject
    private Fizz fizz;

    private Buzz buzz;

    // rest of class omitted for brevity
}

Fizz注入する esの 2 種類があるように、Guice モジュールを構成したいと思います。

  1. 特別なグローバル シングルトンFizzインスタンス。と
  2. その他の (特別ではない)Fizzインスタンス

MyPOJO特別な/シングルトン インスタンスを注入したい。だから私は自分のコードを変更しました:

public class MyPOJO {
    @Inject @Named("Special-Fizz")
    private Fizz fizz;

    private Buzz buzz;

    // rest of class omitted for brevity
}

次に、私のモジュールで:

public class MyModule extends AbstractModule {
    @Override
    public void configure() {
        bind(Fizz.class).annotatedWith(
            Names.named("Special-Fizz"))
            .to(Fizz.class);

        // Other bindings here...
    }

    @Provides @Singleton
    private Fizz providesFizz() {
        return new Fizz(true, "Special", 12.0);
    }
}

しかし、これを単体テスト(JUnit 4.10)しようとすると:

public class MyTest {
    @Named("Special-Fizz") private Fizz specialFizz;

    @Test
    public void usingNamedShouldInjectSpecialFizz() {
        MyModule mod = new MyModule();
        Injector injector = Guice.createInjector(mod);

        specialFizz = injector.getInstance(Fizz.class);

        Assert.assertTrue(specialFizz != null);
    }
}

これはパスします。ここまでは順調ですね。しかし、specialFizzフィールドの名前を変更すると:

    @Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz;

テストを再実行しても、まだ合格です。どうして?!?ここでどこに迷うのですか?前もって感謝します。

4

2 に答える 2

5

非常に奇妙な。Named注入しているバインディングが見つからない場合、Guice は文句を言うべきです。しかし、私はあなたのテストに少し混乱しています。私は何をするかわかりませんinjector.inject。ということinjectMembersですか?実際に POJO のインスタンスを取得し、期待どおりに動作していることを確認する方が理にかなっている場合があります。たぶん次のようなもの:

public class FizzTest {

  public static class MyModule extends AbstractModule {
    @Override
    protected void configure() {
    }

    @Provides
    @Singleton
    @Named("Special-Fizz")
    public Fizz providesFizz() {
      return new Fizz(true);
    }
  }

  public static class Fizz {
    boolean special = false;
    public Fizz() {}
    public Fizz(boolean special) {
      this.special = special;
    }
  }

  public static class MyPOJO {
    @Inject @Named("Special-Fizz")
    private Fizz fizz;

    @Inject
    private Fizz otherFizz;
  }

  @Test
  public void test() {
    MyModule mod = new MyModule();
    Injector injector = Guice.createInjector(mod);

    MyPOJO pojo = injector.getInstance(MyPOJO.class);
    assertTrue(pojo.fizz.special);
    assertTrue(!pojo.otherFizz.special);
  }

}
于 2013-02-09T01:44:25.533 に答える
2

Guice は@Providesメソッドを確認し、喜んでそれを使用してFizz. の特別なインスタンスが必要な場合はFizz、メソッドから注釈を削除してprovidesFizz()、代わりにバインドできます

bind(Fizz.class)
    .annotatedWith(Names.named("Special-Fizz")
    .toInstance(providesFizz());

Fizzこのようにして、どちらを「Special-Fizz」として使用するかを Guice に正確に伝え、Fizzそれ以外の場合は「通常どおり」注入させます。

免責事項:あなたのようなセットアップを実際に試したことはありませんが、同様のセットアップを使用しました. うまくいくかどうか教えてください。

于 2013-02-08T21:58:39.900 に答える