Hilt जैसे डिपेंडेंसी इंजेक्शन फ़्रेमवर्क के इस्तेमाल का एक फ़ायदा यह है कि इससे आपके कोड की जांच करना आसान हो जाता है.
यूनिट टेस्ट
यूनिट टेस्ट के लिए Hilt की ज़रूरत नहीं होती, क्योंकि कॉन्स्ट्रक्टर इंजेक्शन का इस्तेमाल करने वाली क्लास की जांच करते समय, आपको उस क्लास को इंस्टैंशिएट करने के लिए Hilt का इस्तेमाल करने की ज़रूरत नहीं होती. इसके बजाय, आप नकली या मॉक पास करके सीधे क्लास कंस्ट्रक्टर को कॉल कर सकते है डिपेंडेंसी, जैसा कि कंस्ट्रक्टर के एनोटेट न होने पर किया जाता:
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
डिपेंडेंसी शामिल करें:
ग्रूवी
dependencies { // For Robolectric tests. testImplementation 'com.google.dagger:hilt-android-testing:2.51.1' // ...with Kotlin. kaptTest 'com.google.dagger:hilt-android-compiler:2.51.1' // ...with Java. testAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.51.1' // For instrumented tests. androidTestImplementation 'com.google.dagger:hilt-android-testing:2.51.1' // ...with Kotlin. kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.51.1' // ...with Java. androidTestAnnotationProcessor 'com.google.dagger:hilt-android-compiler:2.51.1' }
Kotlin
dependencies { // For Robolectric tests. testImplementation("com.google.dagger:hilt-android-testing:2.51.1") // ...with Kotlin. kaptTest("com.google.dagger:hilt-android-compiler:2.51.1") // ...with Java. testAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.51.1") // For instrumented tests. androidTestImplementation("com.google.dagger:hilt-android-testing:2.51.1") // ...with Kotlin. kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.51.1") // ...with Java. androidTestAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.51.1") }
यूज़र इंटरफ़ेस (यूआई) की जांच करने के लिए सेटअप
आपको ऐसे किसी भी यूज़र इंटरफ़ेस (यूआई) टेस्ट के बारे में एनोटेट करना होगा जिसमें @HiltAndroidTest
के साथ Hilt का इस्तेमाल किया गया है. यह
एनोटेशन की मदद से, हर टेस्ट के लिए 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. }
इसके बाद, आपके टेस्ट को Hilt की उस Application
क्लास के बारे में जानकारी होनी चाहिए
आपके लिए अपने-आप जनरेट होता है.
ऐप्लिकेशन की जांच करें
आपको इंस्ट्रुमेंट किए गए ऐसे टेस्ट करने होंगे जो किसी Application
ऑब्जेक्ट में Hilt का इस्तेमाल करते हैं
जो Hilt के साथ काम करती है. टेस्ट में इस्तेमाल करने के लिए, लाइब्रेरी में HiltTestApplication
की सुविधा उपलब्ध है.
अगर आपकी जांच के लिए किसी दूसरे बेस ऐप्लिकेशन की ज़रूरत है, तो इसके लिए कस्टम ऐप्लिकेशन देखें
टेस्ट.
आपको अपने इंस्ट्रुमेंट्ड में चलने के लिए अपना टेस्ट ऐप्लिकेशन सेट करना होगा परीक्षण या Robolectric टेस्ट किए जा सकते हैं. नीचे दिए गए निर्देशों को खास तौर पर Hilt के लिए है, लेकिन ये सामान्य दिशा-निर्देश हैं कि में दिया जा सकता है.
इंस्ट्रूमेंट किए गए टेस्ट में टेस्ट ऐप्लिकेशन सेट करना
इंस्ट्रुमेंट्ड में Hilt टेस्ट ऐप्लिकेशन का इस्तेमाल करने के लिए टेस्ट, आपको एक नया टेस्ट रनर कॉन्फ़िगर करना होगा. इससे Hilt आपके प्रोजेक्ट में मौजूद सभी इंस्ट्रुमेंटेड टेस्ट के लिए काम करता है. परफ़ॉर्म करें यहां बताया गया तरीका अपनाएं:
- ऐसी कस्टम क्लास बनाएं जो बड़ी हो
AndroidJUnitRunner
इंचandroidTest
फ़ोल्डर. newApplication
फ़ंक्शन को बदलें और जनरेट किए गए Hilt टेस्ट ऐप्लिकेशन का नाम डालें.
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 फ़ाइल में इस टेस्ट रनर को कॉन्फ़िगर करें. इसके लिए, इंस्ट्रुमेंट की गई यूनिट टेस्ट की गाइड में दिया गया तरीका अपनाएं. पक्का करें कि आप पूरे क्लासपाथ का इस्तेमाल करते हैं:
ग्रूवी
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
इसके अलावा, हर टेस्ट के लिए अलग-अलग ऐप्लिकेशन को कॉन्फ़िगर किया जा सकता है
Robolectric @Config
एनोटेशन का इस्तेमाल करके:
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 प्लग इन' के 4.2 से पहले वाले वर्शन का इस्तेमाल किया जा रहा है, तो
स्थानीय यूनिट टेस्ट में @AndroidEntryPoint
क्लास को पूरी तरह बदलना
आपके मॉड्यूल की build.gradle
फ़ाइल में नीचे दिया गया कॉन्फ़िगरेशन:
Groovy
hilt { enableTransformForLocalTests = true }
Kotlin
hilt { enableTransformForLocalTests = true }
हिट में enableTransformForLocalTests
के बारे में ज़्यादा जानकारी
दस्तावेज़.
सुविधाएं टेस्ट करना
जब Hilt आपके परीक्षणों में इस्तेमाल के लिए तैयार हो जाए, तो आप इन कामों के लिए कई सुविधाओं का इस्तेमाल कर सकते हैं टेस्टिंग प्रोसेस को अपनी ज़रूरत के मुताबिक बनाने के लिए किया जा सकता है.
जांच में टाइप इंजेक्ट करना
टेस्ट में टाइप इंजेक्ट करने के लिए, फ़ील्ड इंजेक्शन के लिए @Inject
का इस्तेमाल करें. Hilt को यह बताने के लिए कि
@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
बाइंडिंग को बदलने के लिए, test
या androidTest
फ़ोल्डर में नकली डिपेंडेंसी वाला नया Hilt मॉड्यूल बनाएं और उस पर @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
का इस्तेमाल करें.
नई वैल्यू बाइंड करना
अपने टेस्ट के फ़ील्ड को Hilt में आसानी से बाइंड करने के लिए, @BindValue
एनोटेशन का इस्तेमाल करें
डिपेंडेंसी ग्राफ़. किसी फ़ील्ड को @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 }
अगर आपको मल्टीबाइंडिंग जोड़नी है, तो @BindValue
के बजाय @BindValueIntoSet
और @BindValueIntoMap
एनोटेशन का इस्तेमाल किया जा सकता है. @BindValueIntoMap
के लिए ज़रूरी है कि आप फ़ील्ड के बारे में व्याख्या करें
शामिल किया जा सकता है.
विशेष मामले
Hilt में ऐसी सुविधाएं मौजूद हैं जिनकी मदद से, स्टैंडर्ड टूल का इस्तेमाल नहीं किया जा सकता.
जांच के लिए कस्टम ऐप्लिकेशन
अगर आप HiltTestApplication
का इस्तेमाल नहीं कर पा रहे हैं, क्योंकि आपके टेस्ट ऐप्लिकेशन को ये काम करने होंगे
किसी अन्य ऐप्लिकेशन का विस्तार करें, उसकी
@CustomTestApplication
, जिस बेस क्लास की वैल्यू पास करनी है उसे
बढ़ाने के लिए Hilt ऐप्लिकेशन जनरेट किया गया.
@CustomTestApplication
ऐसी Application
क्लास जनरेट करेगा जो जांच के लिए तैयार है
Hilt के साथ मौजूद है. यह पैरामीटर के तौर पर पास किए गए ऐप्लिकेशन को आगे बढ़ाता है.
Kotlin
@CustomTestApplication(BaseApplication::class) interface HiltTestApplication
Java
@CustomTestApplication(BaseApplication.class) interface HiltTestApplication { }
उदाहरण में, Hilt HiltTestApplication_Application
क्लास को एक्सटेंड करने वाला Application
नाम का HiltTestApplication_Application
जनरेट करता है. तय सीमा में
आम तौर पर, जनरेट किए गए ऐप्लिकेशन का नाम ही एनोटेशन होता है.
क्लास को _Application
से जोड़ा गया. आपको जनरेट किए गए Hilt टेस्ट ऐप्लिकेशन को, इंस्ट्रुमेंट किए गए टेस्ट या Robolectric टेस्ट में चलाने के लिए सेट करना होगा. इस बारे में टेस्ट ऐप्लिकेशन में बताया गया है.
आपके इंस्ट्रुमेंट किए गए टेस्ट में एक से ज़्यादा 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
पहले लागू करता है. @Rule
एनोटेशन में order
एट्रिब्यूट का इस्तेमाल करके, लागू करने का क्रम तय करें. यह सिर्फ़ 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. }
लॉन्चफ़्रैगमेंटइनकंटेनर
launchFragmentInContainer
का इस्तेमाल
Hilt के साथ androidx.fragment:fragment-testing
लाइब्रेरी, क्योंकि यह एक
गतिविधि जो @AndroidEntryPoint
के साथ एनोटेट नहीं की गई है.
इसका इस्तेमाल करें
launchFragmentInHiltContainer
कोड से
architecture-samples
GitHub
डेटा स्टोर करने की जगह का इस्तेमाल करें.
सिंगलटन कॉम्पोनेंट उपलब्ध होने से पहले, एंट्री पॉइंट का इस्तेमाल करना
जब कोई हिल्ट एंट्री होती है, तो @EarlyEntryPoint
एनोटेशन एक एस्केप हैच देता है
में सिंगलटन कॉम्पोनेंट उपलब्ध होने से पहले पॉइंट बनाना ज़रूरी है
हिल्ट टेस्ट.
@EarlyEntryPoint
के बारे में ज़्यादा जानकारी के लिए,
Hilt के दस्तावेज़ देखें.