私はさらに別の方法を見つけたようで、これまでのところ機能しています。
まず、コンポーネント自体ではないコンポーネント インターフェイス:
MyComponent.java
interface MyComponent {
Foo provideFoo();
}
次に、実際のモジュールとテスト用の 2 つの異なるモジュールがあります。
MyModule.java
@Module
class MyModule {
@Provides
public Foo getFoo() {
return new Foo();
}
}
TestModule.java
@Module
class TestModule {
private Foo foo;
public void setFoo(Foo foo) {
this.foo = foo;
}
@Provides
public Foo getFoo() {
return foo;
}
}
そして、これら 2 つのモジュールを使用するための 2 つのコンポーネントがあります。
MyRealComponent.java
@Component(modules=MyModule.class)
interface MyRealComponent extends MyComponent {
Foo provideFoo(); // without this dagger will not do its magic
}
MyTestComponent.java
@Component(modules=TestModule.class)
interface MyTestComponent extends MyComponent {
Foo provideFoo();
}
アプリケーションでは、次のようにします。
MyComponent component = DaggerMyRealComponent.create();
<...>
Foo foo = component.getFoo();
テストコードでは、次を使用します。
TestModule testModule = new TestModule();
testModule.setFoo(someMockFoo);
MyComponent component = DaggerMyTestComponent.builder()
.testModule(testModule).build();
<...>
Foo foo = component.getFoo(); // will return someMockFoo
問題は、MyModule のすべてのメソッドを TestModule にコピーする必要があることですが、外部から直接設定しない限り、TestModule 内に MyModule を配置し、MyModule のメソッドを使用することで実現できます。このような:
TestModule.java
@Module
class TestModule {
MyModule myModule = new MyModule();
private Foo foo = myModule.getFoo();
public void setFoo(Foo foo) {
this.foo = foo;
}
@Provides
public Foo getFoo() {
return foo;
}
}