Add test coverage for Hilt subcomponents using `@TestInstallIn`.
When looking at a recent issue (https://github.com/google/dagger/issues/3695) I realized we didn't actually have test coverage for `@TestInstallIn` for components other than `SingletonComponent`. This CL adds tests for `ActivityComponent` and `FragmentComponent`.
RELNOTES=N/A
PiperOrigin-RevId: 501018396
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/AndroidManifest.xml b/javatests/dagger/hilt/android/testing/testinstallin/AndroidManifest.xml
new file mode 100644
index 0000000..9a2580e
--- /dev/null
+++ b/javatests/dagger/hilt/android/testing/testinstallin/AndroidManifest.xml
@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="dagger.hilt.android.testing.testinstallin">
+
+ <application>
+ <activity
+ android:name=".TestInstallInFooTest$TestActivity"
+ android:exported="false"
+ tools:ignore="MissingClass"/>
+ </application>
+</manifest>
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/BUILD b/javatests/dagger/hilt/android/testing/testinstallin/BUILD
index ff26292..352a388 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/BUILD
+++ b/javatests/dagger/hilt/android/testing/testinstallin/BUILD
@@ -19,6 +19,7 @@
android_local_test(
name = "TestInstallInFooTest",
srcs = ["TestInstallInFooTest.java"],
+ manifest = "AndroidManifest.xml",
manifest_values = {
"minSdkVersion": "15",
"targetSdkVersion": "27",
@@ -27,8 +28,14 @@
":TestInstallInModules",
"//:android_local_test_exports",
"//:dagger_with_compiler",
+ "//java/dagger/hilt/android:android_entry_point",
"//java/dagger/hilt/android/testing:hilt_android_test",
"//third_party/java/truth",
+ "@maven//:androidx_activity_activity",
+ "@maven//:androidx_fragment_fragment",
+ "@maven//:androidx_lifecycle_lifecycle_common",
+ "@maven//:androidx_lifecycle_lifecycle_viewmodel",
+ "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate",
"@maven//:androidx_test_core",
"@maven//:androidx_test_ext_junit",
"@maven//:junit_junit",
@@ -98,5 +105,10 @@
"//java/dagger/hilt:install_in",
"//java/dagger/hilt/android/components",
"//java/dagger/hilt/testing:test_install_in",
+ "@maven//:androidx_activity_activity",
+ "@maven//:androidx_fragment_fragment",
+ "@maven//:androidx_lifecycle_lifecycle_common",
+ "@maven//:androidx_lifecycle_lifecycle_viewmodel",
+ "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate",
],
)
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java
index beb198c..a322125 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java
@@ -20,8 +20,8 @@
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalBarModule;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalFooModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonFooModule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
@@ -33,12 +33,12 @@
@Test
public void testFoo() {
- assertThat(getMyApplication().foo.moduleClass).isEqualTo(GlobalFooModule.class);
+ assertThat(getMyApplication().foo.moduleClass).isEqualTo(SingletonFooModule.class);
}
@Test
public void testBar() {
- assertThat(getMyApplication().bar.moduleClass).isEqualTo(GlobalBarModule.class);
+ assertThat(getMyApplication().bar.moduleClass).isEqualTo(SingletonBarModule.class);
}
private static TestInstallInApp getMyApplication() {
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java
index 8cf9de7..8c733a1 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java
@@ -28,8 +28,8 @@
import dagger.hilt.android.testing.UninstallModules;
import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Bar;
import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Foo;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalBarModule;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonFooTestModule;
import dagger.hilt.components.SingletonComponent;
import javax.inject.Inject;
import org.junit.Rule;
@@ -41,7 +41,7 @@
* Tests that Foo uses the global {@linkplain TestInstallIn} module and that Bar uses the local
* {@linkplain InstallIn} module due to {@linkplain UninstallModules}.
*/
-@UninstallModules(GlobalBarModule.class)
+@UninstallModules(SingletonBarModule.class)
@HiltAndroidTest
@RunWith(AndroidJUnit4.class)
@Config(application = HiltTestApplication.class)
@@ -51,7 +51,7 @@
@Module
@InstallIn(SingletonComponent.class)
- public interface LocalBarTestModule {
+ interface LocalBarTestModule {
@Provides
static Bar provideBar() {
return new Bar(LocalBarTestModule.class);
@@ -64,7 +64,7 @@
@Test
public void testFoo() {
hiltRule.inject();
- assertThat(foo.moduleClass).isEqualTo(GlobalFooTestModule.class);
+ assertThat(foo.moduleClass).isEqualTo(SingletonFooTestModule.class);
}
@Test
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java
index 8a78157..2311431 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java
@@ -18,14 +18,24 @@
import static com.google.common.truth.Truth.assertThat;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import dagger.hilt.android.AndroidEntryPoint;
import dagger.hilt.android.testing.HiltAndroidRule;
import dagger.hilt.android.testing.HiltAndroidTest;
import dagger.hilt.android.testing.HiltTestApplication;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.ActivityBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.ActivityFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.ActivityLevel;
import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Bar;
import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Foo;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalBarModule;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.FragmentBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.FragmentFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.FragmentLevel;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonFooTestModule;
import javax.inject.Inject;
import org.junit.Rule;
import org.junit.Test;
@@ -43,15 +53,71 @@
@Inject Foo foo;
@Inject Bar bar;
- @Test
- public void testFoo() {
- hiltRule.inject();
- assertThat(foo.moduleClass).isEqualTo(GlobalFooTestModule.class);
+ @AndroidEntryPoint(FragmentActivity.class)
+ public static final class TestActivity extends Hilt_TestInstallInFooTest_TestActivity {
+ @Inject @ActivityLevel Foo foo;
+ @Inject @ActivityLevel Bar bar;
+ }
+
+ @AndroidEntryPoint(Fragment.class)
+ public static final class TestFragment extends Hilt_TestInstallInFooTest_TestFragment {
+ @Inject @FragmentLevel Foo foo;
+ @Inject @FragmentLevel Bar bar;
}
@Test
- public void testBar() {
+ public void testSingletonFooUsesTestInstallIn() {
hiltRule.inject();
- assertThat(bar.moduleClass).isEqualTo(GlobalBarModule.class);
+ assertThat(foo.moduleClass).isEqualTo(SingletonFooTestModule.class);
+ }
+
+ @Test
+ public void testSingletonBarUsesInstallIn() {
+ hiltRule.inject();
+ assertThat(bar.moduleClass).isEqualTo(SingletonBarModule.class);
+ }
+
+ @Test
+ public void testActivityFooUsesTestInstallIn() {
+ try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+ scenario.onActivity(
+ activity -> assertThat(activity.foo.moduleClass).isEqualTo(ActivityFooTestModule.class));
+ }
+ }
+
+ @Test
+ public void testActivityBarUsesInstallIn() {
+ try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+ scenario.onActivity(
+ activity -> assertThat(activity.bar.moduleClass).isEqualTo(ActivityBarModule.class));
+ }
+ }
+
+ @Test
+ public void testFragmentFooUsesTestInstallIn() {
+ try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+ scenario.onActivity(
+ activity -> assertThat(getTestFragment(activity).foo.moduleClass)
+ .isEqualTo(FragmentFooTestModule.class));
+ }
+ }
+
+ @Test
+ public void testFragmentBarUsesInstallIn() {
+ try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+ scenario.onActivity(
+ activity -> assertThat(getTestFragment(activity).bar.moduleClass)
+ .isEqualTo(FragmentBarModule.class));
+ }
+ }
+
+ private TestFragment getTestFragment(FragmentActivity activity) {
+ TestFragment fragment = new TestFragment();
+ activity
+ .getSupportFragmentManager()
+ .beginTransaction()
+ .add(fragment, null)
+ .commitNow();
+ return fragment;
}
}
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java
index ab15d98..81d1c00 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java
@@ -16,16 +16,27 @@
package dagger.hilt.android.testing.testinstallin;
+import android.app.Activity;
+import androidx.fragment.app.Fragment;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
+import dagger.hilt.android.components.ActivityComponent;
+import dagger.hilt.android.components.FragmentComponent;
import dagger.hilt.components.SingletonComponent;
import dagger.hilt.testing.TestInstallIn;
+import javax.inject.Qualifier;
/** Modules and classes used in TestInstallInFooTest and TestInstallInBarTest. */
final class TestInstallInModules {
private TestInstallInModules() {}
+ @Qualifier
+ public @interface ActivityLevel {}
+
+ @Qualifier
+ public @interface FragmentLevel {}
+
static class Foo {
Class<?> moduleClass;
@@ -44,28 +55,92 @@
@Module
@InstallIn(SingletonComponent.class)
- interface GlobalFooModule {
+ interface SingletonFooModule {
@Provides
static Foo provideFoo() {
- return new Foo(GlobalFooModule.class);
+ return new Foo(SingletonFooModule.class);
}
}
@Module
@InstallIn(SingletonComponent.class)
- interface GlobalBarModule {
+ interface SingletonBarModule {
@Provides
static Bar provideFoo() {
- return new Bar(GlobalBarModule.class);
+ return new Bar(SingletonBarModule.class);
}
}
@Module
- @TestInstallIn(components = SingletonComponent.class, replaces = GlobalFooModule.class)
- interface GlobalFooTestModule {
+ @TestInstallIn(components = SingletonComponent.class, replaces = SingletonFooModule.class)
+ interface SingletonFooTestModule {
@Provides
static Foo provideFoo() {
- return new Foo(GlobalFooTestModule.class);
+ return new Foo(SingletonFooTestModule.class);
+ }
+ }
+
+ @Module
+ @InstallIn(ActivityComponent.class)
+ interface ActivityFooModule {
+ @Provides
+ @ActivityLevel
+ static Foo provideFoo() {
+ throw new AssertionError("This provides method should never be called.");
+ }
+ }
+
+ @Module
+ @InstallIn(ActivityComponent.class)
+ interface ActivityBarModule {
+ @Provides
+ @ActivityLevel
+ // Add an activity dependency to make sure Dagger adds this module to the correct component.
+ static Bar provideFoo(@SuppressWarnings("UnusedVariable") Activity activity) {
+ return new Bar(ActivityBarModule.class);
+ }
+ }
+
+ @Module
+ @TestInstallIn(components = ActivityComponent.class, replaces = ActivityFooModule.class)
+ interface ActivityFooTestModule {
+ @Provides
+ @ActivityLevel
+ // Add an activity dependency to make sure Dagger adds this module to the correct component.
+ static Foo provideFoo(@SuppressWarnings("UnusedVariable") Activity activity) {
+ return new Foo(ActivityFooTestModule.class);
+ }
+ }
+
+ @Module
+ @InstallIn(FragmentComponent.class)
+ interface FragmentFooModule {
+ @Provides
+ @FragmentLevel
+ static Foo provideFoo() {
+ throw new AssertionError("This provides method should never be called.");
+ }
+ }
+
+ @Module
+ @InstallIn(FragmentComponent.class)
+ interface FragmentBarModule {
+ @Provides
+ @FragmentLevel
+ // Add a fragment dependency to make sure Dagger adds this module to the correct component.
+ static Bar provideFoo(@SuppressWarnings("UnusedVariable") Fragment fragment) {
+ return new Bar(FragmentBarModule.class);
+ }
+ }
+
+ @Module
+ @TestInstallIn(components = FragmentComponent.class, replaces = FragmentFooModule.class)
+ interface FragmentFooTestModule {
+ @Provides
+ @FragmentLevel
+ // Add a fragment dependency to make sure Dagger adds this module to the correct component.
+ static Foo provideFoo(@SuppressWarnings("UnusedVariable") Fragment fragment) {
+ return new Foo(FragmentFooTestModule.class);
}
}
}