אחד היתרונות של שימוש ב-frameworks של הזרקת תלות כמו Hilt הוא מאפשר לבדוק את הקוד בקלות רבה יותר.
בדיקות יחידה (unit testing)
Hilt לא נחוץ לבדיקות יחידה, כי כשבודקים מחלקה שמשתמשת החדרת constructor, לא צריך להשתמש ב-Hilt כדי ליצור את המחלקה הזו. במקום זאת, תוכלו לקרוא ישירות ל-constructor של הכיתה על ידי העברת זיוף או חיקוי של יחסי התלות, בדיוק כמו שהיית עושה אם לא היו מוסיפים הערות ל-constructor:
Kotlin
@ActivityScoped class AnalyticsAdapter @Inject constructor( private val service: AnalyticsService ) { ... } class AnalyticsAdapterTest { @Test fun `Happy path`() { // You don't need Hilt to create an instance of AnalyticsAdapter. // You can pass a fake or mock AnalyticsService. val adapter = AnalyticsAdapter(fakeAnalyticsService) assertEquals(...) } }
Java
@ActivityScope public class AnalyticsAdapter { private final AnalyticsService analyticsService; @Inject AnalyticsAdapter(AnalyticsService analyticsService) { this.analyticsService = analyticsService; } } public final class AnalyticsAdapterTest { @Test public void happyPath() { // You don't need Hilt to create an instance of AnalyticsAdapter. // You can pass a fake or mock AnalyticsService. AnalyticsAdapter adapter = new AnalyticsAdapter(fakeAnalyticsService); assertEquals(...); } }
בדיקות מקצה לקצה
בבדיקות שילוב, Hilt מחדיר יחסי תלות כמו שצריך בסביבת הייצור לא נדרשת תחזוקה באמצעות Hilt, כי הבדיקה אוטומטית של Hilt יוצרת קבוצה חדשה של רכיבים לכל בדיקה.
הוספת יחסי תלות לבדיקה
כדי להשתמש ב-Hilt בבדיקות שלך, עליך לכלול את התלות hilt-android-testing
ב
project:
מגניב
dependencies { // For Robolectric tests. testImplementation 'com.google.dagger:hilt-android-testing:2.44' // ...with Kotlin. kaptTest 'com.google.dagger:hilt-android-compiler:2.44' // ...with Java. testAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.44' // For instrumented tests. androidTestImplementation 'com.google.dagger:hilt-android-testing:2.44' // ...with Kotlin. kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.44' // ...with Java. androidTestAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.44' }
Kotlin
dependencies { // For Robolectric tests. testImplementation("com.google.dagger:hilt-android-testing:2.44") // ...with Kotlin. kaptTest("com.google.dagger:hilt-android-compiler:2.44") // ...with Java. testAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.44") // For instrumented tests. androidTestImplementation("com.google.dagger:hilt-android-testing:2.44") // ...with Kotlin. kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.44") // ...with Java. androidTestAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.44") }
הגדרה של בדיקת ממשק המשתמש
עליך להוסיף הערות לכל בדיקה של ממשק משתמש שמשתמשת ב-Hilt עם @HiltAndroidTest
. הזה
אחראית ליצירת רכיבי Hilt בכל בדיקה.
בנוסף, צריך להוסיף את HiltAndroidRule
לכיתת הבדיקה. הוא מנהל את
'רכיבים' והיא משמשת לביצוע הזרקה בבדיקה:
Kotlin
@HiltAndroidTest class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) // UI tests here. }
Java
@HiltAndroidTest public final class SettingsActivityTest { @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); // UI tests here. }
בשלב הבא, עליך לדעת בבדיקה על הכיתה Application
ש-Hhilt
יוצרת עבורכם אוטומטית.
בדיקת הבקשה
צריך לבצע בדיקות עם כלים אינסטרומנטליים שמשתמשים ב-Hilt באובייקט Application
שתומך ב-Hhilt. הספרייה מספקת HiltTestApplication
לשימוש בבדיקות.
אם הבדיקות צריכות להשתמש באפליקציה בסיסית אחרת, אפשר לעיין באפליקציה מותאמת אישית עבור
בדיקות.
צריך להגדיר את אפליקציית הבדיקה להרצה במכשיר בדיקות או Robolectric בדיקות. ההוראות הבאות לא ספציפיים ל-Hilt, אבל אלה הנחיות כלליות שמסבירות איך לציין כדי להריץ בדיקות.
הגדרת אפליקציית הבדיקה בבדיקות אינסטרומנטליות
כדי להשתמש באפליקציה למבחן Hilt בכלים בדיקות, עליכם להגדיר תוכנת הרצה חדשה. כך Hilt יכול לעבוד עם כל הבדיקות האינסטרומנטטיביות בפרויקט. ביצוע את השלבים הבאים:
- יצירת כיתה בהתאמה אישית שמתרחבת
AndroidJUnitRunner
אינץ' התיקייהandroidTest
- ביטול הפונקציה
newApplication
והעברתה בשם השהיה של יישום הבדיקה.
Kotlin
// A custom runner to set up the instrumented application class for tests. class CustomTestRunner : AndroidJUnitRunner() { override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application { return super.newApplication(cl, HiltTestApplication::class.java.name, context) } }
Java
// A custom runner to set up the instrumented application class for tests. public final class CustomTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException { return super.newApplication(cl, HiltTestApplication.class.getName(), context); } }
בשלב הבא, מגדירים את תוכנת הבדיקה בקובץ Gradle, כפי שמתואר בדיקת יחידה אינסטרומנטלית guide. כדאי לוודא משתמשים בנתיב הכיתה המלא:
מגניב
android { defaultConfig { // Replace com.example.android.dagger with your class path. testInstrumentationRunner "com.example.android.dagger.CustomTestRunner" } }
Kotlin
android { defaultConfig { // Replace com.example.android.dagger with your class path. testInstrumentationRunner = "com.example.android.dagger.CustomTestRunner" } }
הגדרת אפליקציית הבדיקה בבדיקות Robolectric
אם משתמשים ב-Robolectric כדי לבדוק את השכבה של ממשק המשתמש, אפשר לציין איזו אפליקציה
לשימוש בקובץ robolectric.properties
:
application = dagger.hilt.android.testing.HiltTestApplication
לחלופין, אפשר להגדיר את האפליקציה בכל בדיקה בנפרד באמצעות
באמצעות הערת @Config
של Robolectric:
Kotlin
@HiltAndroidTest @Config(application = HiltTestApplication::class) class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) // Robolectric tests here. }
Java
@HiltAndroidTest @Config(application = HiltTestApplication.class) class SettingsActivityTest { @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); // Robolectric tests here. }
אם משתמשים בגרסה של Android Gradle Plugin ישנה יותר מ-4.2, יש להפעיל את התכונה
לשנות @AndroidEntryPoint
מחלקות בבדיקות יחידה מקומית על ידי החלת
את התצורה הבאה בקובץ build.gradle
של המודול שלך:
מגניב
hilt { enableTransformForLocalTests = true }
Kotlin
hilt { enableTransformForLocalTests = true }
מידע נוסף על enableTransformForLocalTests
בקטע הילט
תיעוד.
תכונות בדיקה
ברגע ש-Hilt יהיה מוכן לשימוש בבדיקות שלכם, תוכלו להשתמש במספר תכונות כדי להתאים אישית את תהליך הבדיקה.
סוגי החדרה בבדיקות
כדי להזריק סוגים לבדיקה, צריך להשתמש ב-@Inject
להחדרת שדה. כדי לומר ל-Hhilt
לאכלס את השדות @Inject
, קוראים לפונקציה hiltRule.inject()
.
לפניכם דוגמה לבדיקה של מכשיר אינסטרומנטלי:
Kotlin
@HiltAndroidTest class SettingsActivityTest { @get:Rule var hiltRule = HiltAndroidRule(this) @Inject lateinit var analyticsAdapter: AnalyticsAdapter @Before fun init() { hiltRule.inject() } @Test fun `happy path`() { // Can already use analyticsAdapter here. } }
Java
@HiltAndroidTest public final class SettingsActivityTest { @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); @Inject AnalyticsAdapter analyticsAdapter; @Before public void init() { hiltRule.inject(); } @Test public void happyPath() { // Can already use analyticsAdapter here. } }
החלפת קישור
אם צריך להחדיר מופע מזויף או מופע מדומה של תלות, עליך להודיע לא להשתמש בקישור שבו נעשה שימוש בקוד הייצור, ולא להשתמש אחרת. כדי להחליף קישור, צריך להחליף את המודול מכילה את הקישור למודול בדיקה שמכיל את הקישורים הרצויים לשימוש בבדיקה.
לדוגמה, נניח שקוד הייצור מצהיר על קישור
AnalyticsService
באופן הזה:
Kotlin
@Module @InstallIn(SingletonComponent::class) abstract class AnalyticsModule { @Singleton @Binds abstract fun bindAnalyticsService( analyticsServiceImpl: AnalyticsServiceImpl ): AnalyticsService }
Java
@Module @InstallIn(SingletonComponent.class) public abstract class AnalyticsModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( AnalyticsServiceImpl analyticsServiceImpl ); }
כדי להחליף את הקישור AnalyticsService
בבדיקות, צריך ליצור מודול Hilt חדש ב-
התיקייה test
או androidTest
עם תלות מזויפת ולהוסיף לה הערות
עם @TestInstallIn
. כל הבדיקות בתיקייה הזו מוחדרות יחד עם
או תלויה במקום זאת.
Kotlin
@Module @TestInstallIn( components = [SingletonComponent::class], replaces = [AnalyticsModule::class] ) abstract class FakeAnalyticsModule { @Singleton @Binds abstract fun bindAnalyticsService( fakeAnalyticsService: FakeAnalyticsService ): AnalyticsService }
Java
@Module @TestInstallIn( components = SingletonComponent.class, replaces = AnalyticsModule.class ) public abstract class FakeAnalyticsModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( FakeAnalyticsService fakeAnalyticsService ); }
החלפת קישור בבדיקה אחת
כדי להחליף קישור בבדיקה יחידה במקום בכל הבדיקות, צריך להסיר את Hilt
מבדיקה באמצעות ההערה @UninstallModules
ויצירת
מודול הבדיקה שבבדיקה.
בהתאם לדוגמה AnalyticsService
של הגרסה הקודמת, צריך להתחיל באמירת הפקודה
השהיה כדי להתעלם ממודול הייצור באמצעות ההערה @UninstallModules
בכיתת הבדיקה:
Kotlin
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { ... }
Java
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest public final class SettingsActivityTest { ... }
בשלב הבא צריך להחליף את הקישור. יצירת מודול חדש בכיתת הבדיקה שמגדיר את קישור הבדיקה:
Kotlin
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { @Module @InstallIn(SingletonComponent::class) abstract class TestModule { @Singleton @Binds abstract fun bindAnalyticsService( fakeAnalyticsService: FakeAnalyticsService ): AnalyticsService } ... }
Java
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest public final class SettingsActivityTest { @Module @InstallIn(SingletonComponent.class) public abstract class TestModule { @Singleton @Binds public abstract AnalyticsService bindAnalyticsService( FakeAnalyticsService fakeAnalyticsService ); } ... }
הפעולה הזו מחליפה את הקישור למחלקה אחת בלבד של בדיקה. אם רוצים להחליף
את הקישור לכל מחלקות הבדיקה, משתמשים בהערה @TestInstallIn
שלמעלה. לחלופין, אפשר להציב את קישור הבדיקה במודול test
לבדיקות רובולקטריות, או במודול androidTest
לבדיקות אינסטרומנטליות.
ההמלצה היא להשתמש ב-@TestInstallIn
כשהדבר אפשרי.
קישור ערכים חדשים
אפשר להשתמש בהערה @BindValue
כדי לקשר בקלות שדות בבדיקה ל-Hilt
בתרשים של יחסי התלות. יש להוסיף הערות לשדה עם @BindValue
, והוא יהיה כפוף מתחת
סוג השדה המוצהר עם כל הגורמים המציינים שקיימים בשדה הזה.
בדוגמה של AnalyticsService
, אפשר להחליף את AnalyticsService
ב-
זיוף באמצעות @BindValue
:
Kotlin
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { @BindValue @JvmField val analyticsService: AnalyticsService = FakeAnalyticsService() ... }
Java
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest class SettingsActivityTest { @BindValue AnalyticsService analyticsService = FakeAnalyticsService(); ... }
זה מפשט את האפשרות להחליף קישור וגם להפנות לקישור בבדיקה בכך שהוא מאפשר לבצע את שתי הפעולות בו-זמנית.
@BindValue
פועל עם מגדירים והערות בדיקה אחרות. לדוגמה,
אם אתם משתמשים בספריות בדיקה כמו
Mockito, אפשר להשתמש בו
בדיקה Robolectric באופן הבא:
Kotlin
... class SettingsActivityTest { ... @BindValue @ExampleQualifier @Mock lateinit var qualifiedVariable: ExampleCustomType // Robolectric tests here }
Java
... class SettingsActivityTest { ... @BindValue @ExampleQualifier @Mock ExampleCustomType qualifiedVariable; // Robolectric tests here }
אם צריך להוסיף ריבוי קישור,
אפשר להשתמש בהערות @BindValueIntoSet
ו-@BindValueIntoMap
במקום
מתוך @BindValue
. לפי הדרישות של @BindValueIntoMap
, צריך גם להוסיף הערות לשדה
עם הערה על מקש במפה.
מקרים מיוחדים
Hilt מספק גם תכונות לתמיכה בתרחישים לא סטנדרטיים.
אפליקציה מותאמת אישית לבדיקות
אם אין לך אפשרות להשתמש ב-HiltTestApplication
כי אפליקציית הבדיקה שלך צריכה
להרחיב אפליקציה נוספת, להוסיף הערות למחלקה או לממשק חדשים עם
@CustomTestApplication
, מעבירים את הערך של מחלקת הבסיס שרוצים
שנוצרה באמצעות Hilt.
מערכת @CustomTestApplication
תיצור כיתת Application
שמוכנה לבדיקה
עם Hilt שמרחיב את האפליקציה שהעברת כפרמטר.
Kotlin
@CustomTestApplication(BaseApplication::class) interface HiltTestApplication
Java
@CustomTestApplication(BaseApplication.class) interface HiltTestApplication { }
בדוגמה, Hilt יוצר Application
בשם
HiltTestApplication_Application
שמרחיבים את המחלקה BaseApplication
. לחשבון
באופן כללי, שם האפליקציה שנוצר הוא שם האפליקציה
הכיתה מצורפת ל-_Application
. עליך להגדיר את בדיקת Hilt שנוצרה
שתרוץ בבדיקות אינסטרומנטליות או
בדיקות רובולקטריות כפי שמתואר בבדיקה
.
מספר אובייקטי TestRule בבדיקה של המכשיר
אם בבדיקה יש TestRule
אובייקטים אחרים, יש כמה דרכים
כדי להבטיח שכל הכללים יפעלו יחד.
אפשר לסכם את כל הכללים באופן הבא:
Kotlin
@HiltAndroidTest class SettingsActivityTest { @get:Rule var rule = RuleChain.outerRule(HiltAndroidRule(this)). around(SettingsActivityTestRule(...)) // UI tests here. }
Java
@HiltAndroidTest public final class SettingsActivityTest { @Rule public RuleChain rule = RuleChain.outerRule(new HiltAndroidRule(this)) .around(new SettingsActivityTestRule(...)); // UI tests here. }
לחלופין, ניתן להשתמש בשני הכללים באותה רמה, כל עוד
HiltAndroidRule
מופעל ראשון. מציינים את סדר הביצוע באמצעות הפקודה
מאפיין order
בהערה @Rule
. זה פועל רק בגרסת JUnit
4.13 ואילך:
Kotlin
@HiltAndroidTest class SettingsActivityTest { @get:Rule(order = 0) var hiltRule = HiltAndroidRule(this) @get:Rule(order = 1) var settingsActivityTestRule = SettingsActivityTestRule(...) // UI tests here. }
Java
@HiltAndroidTest public final class SettingsActivityTest { @Rule(order = 0) public HiltAndroidRule hiltRule = new HiltAndroidRule(this); @Rule(order = 1) public SettingsActivityTestRule settingsActivityTestRule = new SettingsActivityTestRule(...); // UI tests here. }
UnlockFragmentInContainer
לא ניתן להשתמש ב-launchFragmentInContainer
מ-
הספרייה androidx.fragment:fragment-testing
עם Hilt, כי היא מסתמכת על
פעילות שלא מצוינת עבורה הערות ב-@AndroidEntryPoint
.
משתמשים ב
launchFragmentInHiltContainer
מתוך
architecture-samples
GitHub
במקום זאת.
צריך להשתמש בנקודת כניסה לפני שרכיב הסינגלטון זמין
ההערה @EarlyEntryPoint
מספקת פתח מילוט כשרשומת Hilt
צריך ליצור נקודה לפני שרכיב הסינגלטון יהיה זמין
בדיקת השהיה.
מידע נוסף על @EarlyEntryPoint
זמין ב
מסמכי תיעוד של Hilt