1. ホーム
  2. java

[解決済み] Guiceでバインディングをオーバーライドする

2022-04-28 16:42:04

質問

私はGuiceを使い始めたばかりですが、考えられる使用例としては、テストにおいて1つのバインディングを上書きしたいだけです。 私は、すべてが正しく設定されていることを確認し、重複を避けるために、残りの製品レベルのバインディングを使用したいと思います。

そこで、次のようなモジュールがあるとします。

public class ProductionModule implements Module {
    public void configure(Binder binder) {
        binder.bind(InterfaceA.class).to(ConcreteA.class);
        binder.bind(InterfaceB.class).to(ConcreteB.class);
        binder.bind(InterfaceC.class).to(ConcreteC.class);
    }
}

そして、私のテストでは、InterfaceAとInterfaceBはそのままに、InterfaceCだけをオーバーライドしたいので、次のようなものが欲しいです。

Module testModule = new Module() {
    public void configure(Binder binder) {
        binder.bind(InterfaceC.class).to(MockC.class);
    }
};
Guice.createInjector(new ProductionModule(), testModule);

また、次のようなことも試してみましたが、うまくいきません。

Module testModule = new ProductionModule() {
    public void configure(Binder binder) {
        super.configure(binder);
        binder.bind(InterfaceC.class).to(MockC.class);
    }
};
Guice.createInjector(testModule);

私の望むことが可能かどうか、または私が完全に間違った木に吠えているかどうか、誰か知っていますか?

--- フォローアップです。 インターフェイスの @ImplementedBy タグを使用して、テストケースでバインディングを提供すれば、私が望むことを実現できるようです。

また、同僚と話し合った結果、モジュール全体をオーバーライドして、モジュールが正しく定義されていることを確認する道を歩むことになりそうです。 この場合、バインディングがモジュール内で誤って配置され、移動する必要があるため、バインディングをオーバーライドすることができなくなり、多くのテストが壊れる可能性があると思われます。

解決方法は?

これはあなたが探している答えではないかもしれませんが、もしあなたがユニットテストを書いているのなら、おそらくインジェクタを使うべきでなく、むしろモックや偽のオブジェクトを手で注入すべきです。

一方、どうしても1つのバインディングを置き換えたい場合は Modules.override(..) :

public class ProductionModule implements Module {
    public void configure(Binder binder) {
        binder.bind(InterfaceA.class).to(ConcreteA.class);
        binder.bind(InterfaceB.class).to(ConcreteB.class);
        binder.bind(InterfaceC.class).to(ConcreteC.class);
    }
}
public class TestModule implements Module {
    public void configure(Binder binder) {
        binder.bind(InterfaceC.class).to(MockC.class);
    }
}
Guice.createInjector(Modules.override(new ProductionModule()).with(new TestModule()));

詳細を見る こちら .

のjavadocにあるように Modules.overrides(..) は、バインディングをオーバーライドする必要がないようにモジュールを設計することを推奨しています。この例では InterfaceC を別モジュールにする。