Hilt gibi bağımlılık yerleştirme çerçeveleri kullanmanın avantajlarından biri kodunuzu test etmeyi kolaylaştırır.
Birim testleri
oluşturucu enjeksiyonu varsa bu sınıfı örneklendirmek için Hilt'i kullanmanız gerekmez. Bunun yerine, sahte veya sahte dosya ileterek bir sınıf oluşturucuyu doğrudan çağırabilirsiniz. bağımlılıkları, kurucu için açıklama eklenmediğinde yapacağınız gibi:
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(...); } }
Uçtan uca testler
Hilt, entegrasyon testleri için bağımlılıkları üretimde olduğu gibi ekler. girin. Hilt her test için otomatik olarak yeni bir bileşen grubu oluşturduğundan Hilt ile test yapmak için bakım gerekmez.
Test bağımlılıkları ekleme
Hilt'i testlerinizde kullanmak içinhilt-android-testing
proje:
Eski
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") }
Kullanıcı arayüzü test kurulumu
Hilt'i kullanan tüm kullanıcı arayüzü testlerine @HiltAndroidTest
ile açıklama eklemeniz gerekir. Bu
ek açıklaması, her test için Hilt bileşenlerini oluşturmaktan sorumludur.
Ayrıca, HiltAndroidRule
öğesini test sınıfına eklemeniz gerekir.
bileşenler durumudur ve testinize ekleme işlemi gerçekleştirmek için kullanılır:
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. }
Ardından, testinizin Hilt'in sizin için otomatik olarak oluşturduğu Application
sınıfını bilmesi gerekir.
Test uygulaması
Hilt'i destekleyen bir Application
nesnesinde Hilt kullanan enstrümante testler çalıştırmanız gerekir. Kitaplık, testlerde kullanılmak üzere HiltTestApplication
sağlar.
Testleriniz için farklı bir temel uygulamaya ihtiyaç duyuyorsanız Özel uygulama
testlerinde bulabilirsiniz.
Test uygulamanızı, kullandığınız araçlar ile testler veya Robolectric testleriyle ilgili daha fazla bilgi edinin. Aşağıdaki talimatlarda ancak özel bir değerin nasıl belirtileceğine ilişkin genel yönergelerdir. testlerde çalıştırılacak bir uygulamadır.
Test uygulamasını araçlı testlerde ayarlama
Hilt test uygulamasını araçla test edilen testlerde kullanmak için yeni bir test çalıştırıcıyı yapılandırmanız gerekir. Bu sayede Hilt, projenizdeki tüm enstrümante testler için çalışır. Gerçekleştirme şu adımları uygulayın:
- Genişletilen özel bir sınıf oluşturun
AndroidJUnitRunner
inçandroidTest
klasörü. newApplication
işlevini geçersiz kıl ve oluşturulan işlevin adını ilet Hilt test uygulaması.
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); } }
Ardından, bu test çalıştırıcısını Gradle dosyanızda araçlı birim testi rehberini inceleyin. Şunlardan emin olun: sınıf yolunun tamamını kullanırsınız:
Groovy
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 testlerinde test uygulamasını ayarlama
Kullanıcı arayüzü katmanınızı test etmek için Robolectric'i kullanırsanız hangi uygulamanın
robolectric.properties
dosyasında kullanılacak:
application = dagger.hilt.android.testing.HiltTestApplication
Alternatif olarak, aşağıdakileri yaparak uygulamayı her testte ayrı ayrı yapılandırabilirsiniz:
Robolectric'in @Config
ek açıklaması kullanılarak:
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 eklentisi 4.2'den eski bir sürüm kullanıyorsanız
şunu uygulayarak @AndroidEntryPoint
sınıflarını yerel birim testlerinde dönüştürme:
modülünüzün build.gradle
dosyasında aşağıdaki yapılandırmayı uygulayın:
Groovy
hilt { enableTransformForLocalTests = true }
Kotlin
hilt { enableTransformForLocalTests = true }
enableTransformForLocalTests
hakkında daha fazla bilgiyi Hilt belgeleri bölümünde bulabilirsiniz.
Test özellikleri
Hilt, testlerinizde kullanıma hazır olduğunda aşağıdakileri gerçekleştirmek için çeşitli özellikleri kullanabilirsiniz: test sürecini özelleştirebilirsiniz.
Testlere tür ekleme
Bir teste tür eklemek için alan ekleme için @Inject
kullanın. Hilt'e
@Inject
alanlarını doldurmak için hiltRule.inject()
yöntemini çağırın.
Aşağıdaki araçlı test örneğine bakın:
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. } }
Bağlamayı değiştirme
Bir bağımlılığın sahte veya taklit örneğini eklemeniz gerekiyorsa Hilt'e, üretim kodunda kullandığı bağlamayı kullanmamasını ve bunun yerine farklı bir bağlama kullanmasını söylemeniz gerekir. Bir bağlamayı değiştirmek için, tablodaki modülü Google Analytics 4'te, istediğiniz bağlamaları içeren bir test modülüne her zaman olması gerekir.
Örneğin, üretim kodunuzun
AnalyticsService
şöyle:
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 ); }
Testlerdeki AnalyticsService
bağlamasını değiştirmek için test
veya androidTest
klasöründe sahte bağımlılığı olan yeni bir Hilt modülü oluşturun ve @TestInstallIn
ile ek açıklama ekleyin. Bu klasördeki tüm testlere bunun yerine sahte bağımlılık eklenir.
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 ); }
Tek bir testte bağlamayı değiştirme
Tüm testler yerine tek bir testte bir bağlamayı değiştirmek için Hilt'i kaldırın
modülünü kullanarak @UninstallModules
ek açıklamasını kullanarak bir testten yeni bir
test modülünün bir parçası.
Önceki sürümdeki AnalyticsService
örneğini takip ederek, test sınıfında @UninstallModules
ek açıklamasını kullanarak Hilt'e üretim modülünü yoksaymasını söyleyerek başlayın:
Kotlin
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { ... }
Java
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest public final class SettingsActivityTest { ... }
Ardından, cilt kapağını değiştirmeniz gerekir. Test sınıfında yeni bir modül oluşturma şu etiketi tanımlar:
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 ); } ... }
Bu işlem yalnızca tek bir test sınıfının bağlamasını değiştirir. Tüm test sınıflarının bağlamasını değiştirmek istiyorsanız yukarıdaki bölümdeki @TestInstallIn
ek açıklamasını kullanın. Alternatif olarak, test bağlamasını test
modülüne yerleştirebilirsiniz
veya araçlı testler için androidTest
modülünde kullanılabilir.
Mümkün olduğunda @TestInstallIn
kullanmanızı öneririz.
Yeni değerleri bağlama
Testinizdeki alanları Hilt bağımlılık grafiğine kolayca bağlamak için @BindValue
ek açıklamasını kullanın. Bir alana @BindValue
ile ek açıklama eklediğinizde, bu alan, belirtilen alan türünün altına, o alanda bulunan tüm niteliklerle birlikte bağlanır.
AnalyticsService
örneğinde, AnalyticsService
yerine bir
@BindValue
kullanarak sahte:
Kotlin
@UninstallModules(AnalyticsModule::class) @HiltAndroidTest class SettingsActivityTest { @BindValue @JvmField val analyticsService: AnalyticsService = FakeAnalyticsService() ... }
Java
@UninstallModules(AnalyticsModule.class) @HiltAndroidTest class SettingsActivityTest { @BindValue AnalyticsService analyticsService = FakeAnalyticsService(); ... }
Bu, testinizde hem bir bağlamayı değiştirmeyi hem de bir bağlama referans vermeyi kolaylaştırır Böylece her ikisini de aynı anda yapabilirsiniz.
@BindValue
, niteleyicilerle ve diğer test ek açıklamalarıyla çalışır. Örneğin, Mockito gibi test kitaplıklarını kullanıyorsanız bunları Robolectric testinde aşağıdaki gibi kullanabilirsiniz:
Kotlin
... class SettingsActivityTest { ... @BindValue @ExampleQualifier @Mock lateinit var qualifiedVariable: ExampleCustomType // Robolectric tests here }
Java
... class SettingsActivityTest { ... @BindValue @ExampleQualifier @Mock ExampleCustomType qualifiedVariable; // Robolectric tests here }
Bir çoklu bağlama eklemeniz gerekirse:
yerinde @BindValueIntoSet
ve @BindValueIntoMap
ek açıklamalarını kullanabilirsiniz
/ @BindValue
. @BindValueIntoMap
, alana bir harita anahtarı ek açıklaması da eklemenizi gerektirir.
Özel durumlar
Hilt, standart dışı kullanım alanlarını destekleyecek özellikler de sunar.
Testler için özel uygulama
Test uygulamanızın şunu yapması gerektiği için HiltTestApplication
ürününü kullanamıyorsanız
başka bir uygulamayı genişletin, yeni sınıfa veya arayüze
@CustomTestApplication
:
oluşturuldu.
@CustomTestApplication
, test için hazır bir Application
sınıfı oluşturacak
, parametre olarak ilettiğiniz uygulamayı genişleten Hilt ile oluşturun.
Kotlin
@CustomTestApplication(BaseApplication::class) interface HiltTestApplication
Java
@CustomTestApplication(BaseApplication.class) interface HiltTestApplication { }
Örnekte, Hilt, adlı bir Application
BaseApplication
sınıfını genişleten HiltTestApplication_Application
. İçinde
oluşturulan uygulamanın adı, ek açıklama
sınıf _Application
eklendi. Oluşturulan Hilt test uygulamasını, Test uygulaması bölümünde açıklandığı gibi araçlarla testlerinizde veya Robolectric testlerinizde çalıştıracak şekilde ayarlamanız gerekir.
Araçla test edilen testinizde birden fazla TestRule nesnesi
Testinizde başka TestRule
nesneleri de varsa aşağıdakileri yapmanın birden çok yolu vardır:
tüm kuralların birlikte
çalıştığından emin olmaktır.
Kuralları aşağıdaki gibi bir araya getirebilirsiniz:
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. }
Alternatif olarak, HiltAndroidRule
önce çalıştırıldığı sürece her iki kuralı da aynı seviyede kullanabilirsiniz. Yürütme siparişini şunu kullanarak belirtin:
@Rule
ek açıklamasındaki order
özelliği. Bu yalnızca JUnit sürümünde çalışır
4.13 veya sonraki sürümler:
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 içi
Hilt, @AndroidEntryPoint
ile ek açıklama eklenmemiş bir etkinliğe dayandığı için androidx.fragment:fragment-testing
kitaplığındaki launchFragmentInContainer
öğesini Hilt ile kullanmak mümkün değildir.
Şunu kullanın:
launchFragmentInHiltContainer
örneğinden
architecture-samples
GitHub
depo olarak kullanabilirsiniz.
Singleton bileşeni kullanılabilir hale gelmeden önce bir giriş noktası kullanın
@EarlyEntryPoint
ek açıklama, Hilt testinde tekil bileşen kullanılabilir hale gelmeden önce Hilt giriş noktası oluşturulması gerektiğinde bir kaçış yolu sağlar.
@EarlyEntryPoint
hakkında daha fazla bilgi:
Hilt belgeleri.