Hilt test kılavuzu

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ı, oluşturucuya 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 ile test yapmak bakım gerektirmez, çünkü Hilt otomatik olarak her test için yeni bir bileşen grubu oluşturur.

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.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")
}

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. Şunu yönetir: 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.
}

Sonra, testinizde Hilt'in etkinleştirildiği Application sınıfı hakkında bilgi sahibi olması gerekir otomatik olarak oluşturulur.

Test uygulaması

Bir Application nesnesinde Hilt kullanan araçlı testler yürütmeniz gerekir İYS'lerden 16'sını değerlendirdik. 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 testler ile karşılaştırın. 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çlı testler için yeni bir test çalıştırıcı yapılandırmanız gerekir. Bu, Hilt'in projenizdeki tüm araçlı testlerde çalışmasını sağlar. Gerçekleştirme şu adımları uygulayın:

  1. Genişletilen özel bir sınıf oluşturun AndroidJUnitRunner inç androidTest klasörü.
  2. 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:

Eski

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: aşağıdaki yapılandırmayı kullanabilirsiniz:build.gradle

Eski

hilt {
    enableTransformForLocalTests = true
}

Kotlin

hilt {
    enableTransformForLocalTests = true
}

Hilt'teki enableTransformForLocalTests hakkında daha fazla bilgi dokümanlarına göz atın.

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ürleri ekle

Bir teste tür eklemek için alan yerleştirme işleminde @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 sahte örneğini eklemeniz gerekiyorsa bunu Üretim kodunda kullandığı bağlamayı kullanmamak ve isteyebilirsiniz. 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 şurada yeni bir Hilt modülü oluşturun: sahte bağımlılığa sahip test veya androidTest klasörü oluşturup bu bağımlılığa ek açıklama ekleme @TestInstallIn ile. Bu klasördeki tüm testlere, sahte bağımlılığı olabilir.

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 içinde yer alacak.

Önceki sürümdeki AnalyticsService örneğine devam ederek, @UninstallModules ek açıklamasını kullanarak üretim modülünü yoksaymak için dokunun test sınıfında:

Kotlin

@UninstallModules(AnalyticsModule::class)
@HiltAndroidTest
class SettingsActivityTest { ... }

Java

@UninstallModules(AnalyticsModule.class)
@HiltAndroidTest
public final class SettingsActivityTest { ... }

Ardından, bağlamayı değiştirmeniz gerekir. Test sınıfında yeni bir modül oluşturma şu değeri 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, yalnızca tek bir test sınıfı için bağlamanın yerini alır. Tüm URL'leri bağlamayı tercih etmek için@TestInstallIn bölümüne bakı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 kullanılması önerilir.

Yeni değerleri bağlama

Testinizdeki alanları Hilt'e kolayca bağlamak için @BindValue ek açıklamasını kullanın. bağımlılık grafiğidir. Bir alana @BindValue ile not ekleyin. Bu durumda alan belirtilen alan türünü, söz konusu alan için mevcut niteleyicilerle birlikte girin.

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'yu Google ile Aşağıdaki şekilde robotik test:

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 da not vermenizi gerektiriyor eşleme anahtarı ek açıklamasıyla birlikte kullanabilirsiniz.

Ö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 eklenen sınıf _Application eklendi. Oluşturulan Hilt testini ayarlamanız gerekir araçlı testlerinizde çalıştırılacak bir uygulama veya Test bölümünde açıklandığı gibi Robolektrik testler ekleyebilirsiniz.

Araçlı testinizde birden çok 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, Önce HiltAndroidRule yürütülür. 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

launchFragmentInContainer, Hilt ile androidx.fragment:fragment-testing kitaplığı, çünkü @AndroidEntryPoint ile notlanmayan etkinlik.

Şunu kullanın: launchFragmentInHiltContainer örneğinden architecture-samples GitHub kod depoları kullanır.

Singleton bileşeni kullanılabilir hale gelmeden önce bir giriş noktası kullanın

@EarlyEntryPoint ek açıklaması, bir Hilt girişi olduğunda bir kaçış kapısı sağlar tekli bileşeninin bir Kaçap testi.

@EarlyEntryPoint hakkında daha fazla bilgi: Hilt belgeleri.