I have a Gradle application with a project structure similar to Jake Wharton u2020 :
/src /androidTest /debug /main /release
In my application class, I create a dagger graph and insert it:
MyApplication extends Application { ... public void buildObjectGraphAndInject() { Object[] modules = Modules.list(this); mApplicationGraph = ObjectGraph.create(modules); mApplicationGraph.inject(this); } ... }
Inside a set of debugging options, I define Modules.list() as:
public final class Modules { public static Object[] list(MyApplication app) { return new Object[] { new AppModule(app), new DebugAppModule() }; } private Modules() {
Inside the release release set, I define the same minus DebugAppModule:
public final class Modules { public static Object[] list(MyApplication app) { return new Object[] { new AppModule(app) }; } private Modules() {
A deeper dependency graph, I create a MockRestAdapter, which I can use when starting the debug version:
@Module( complete = false, library = true, overrides = true ) public final class DebugApiModule { @Provides @Singleton Endpoint provideEndpoint(@ApiEndpoint StringPreference apiEndpoint) { return Endpoints.newFixedEndpoint(apiEndpoint.get()); } @Provides @Singleton MockRestAdapter provideMockRestAdapter(RestAdapter restAdapter, SharedPreferences preferences) { MockRestAdapter mockRestAdapter = MockRestAdapter.from(restAdapter); AndroidMockValuePersistence.install(mockRestAdapter, preferences); return mockRestAdapter; } @Provides @Singleton MyApi provideMyApi(RestAdapter restAdapter, MockRestAdapter mockRestAdapter, @IsMockMode boolean isMockMode, MockMyApi mockService) { if (isMockMode) { return mockRestAdapter.create(MyApi.class, mockService); } return restAdapter.create(MyApi.class); } }
But while I run the tests, I would like to override DebugApiModule with TestApiModule, which looks like this:
@Module( complete = false, library = true, overrides = true ) public final class TestApiModule { @Provides @Singleton Endpoint provideEndpoint(@ApiEndpoint StringPreference apiEndpoint) { return Endpoints.newFixedEndpoint(apiEndpoint.get()); } @Provides @Singleton MockRestAdapter provideMockRestAdapter(RestAdapter restAdapter, SharedPreferences preferences) { MockRestAdapter mockRestAdapter = MockRestAdapter.from(restAdapter); mockRestAdapter.setDelay(0); mockRestAdapter.setErrorPercentage(0); mockRestAdapter.setVariancePercentage(0); return mockRestAdapter; } @Provides @Singleton MyApi provideMyApi(MockRestAdapter mockRestAdapter, MockHnApi mockService) { return mockRestAdapter.create(MyApi.class, mockService); } }
What is the best way to achieve this? I need to create a TestAppModule as follows:
public final class Modules { public static Object[] list(MyApplication app) { return new Object[] { new AppModule(app), new TestAppModule() }; } private Modules() {
And replace all DebugFooModule with TestFooModules ? If so, how do I get around the fact that Modules.java duplicated? Or am I out of base?
EDIT: SOLUTION
What I ended up with is replacing the application level graph (where the MockRestAdapter is created) during my setUp test
protected void setUp() throws Exception { super.setUp(); HnApp app = HnApp.getInstance(); app.buildObjectGraphAndInject(TestModules.list(app)); getActivity(); }