You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Robolectric和Dagger Hilt启动Fragment时Lateinit字段未注入

Fixing Lateinit Injection Failure with Robolectric + Dagger Hilt for Fragments

Let's break down how to resolve this kotlin.UninitializedPropertyAccessException issue you're facing. I've run into similar problems before, and it usually boils down to small gaps in how the Hilt test container is set up or how Robolectric interacts with Hilt's injection lifecycle.

Step 1: Verify Your launchFragmentInHiltContainer Implementation

The official Hilt documentation's launchFragmentInHiltContainer relies on a Hilt-annotated test activity to properly scope the Fragment's injection. If your implementation is missing this, Hilt can't inject the Fragment's fields.

First, create a simple Hilt-enabled test activity:

@AndroidEntryPoint
class HiltTestActivity : AppCompatActivity()

This activity acts as the host for your Fragment and lets Hilt manage the injection context.

Then, make sure your launchFragmentInHiltContainer function uses this activity correctly:

import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import androidx.annotation.StyleRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.FragmentScenario
import androidx.test.core.app.ApplicationProvider
import com.google.common.base.Preconditions

inline fun <reified T : Fragment> launchFragmentInHiltContainer(
    fragmentArgs: Bundle? = null,
    @StyleRes themeResId: Int = androidx.fragment.testing.R.style.FragmentScenarioEmptyFragmentActivityTheme,
    crossinline action: T.() -> Unit = {}
) {
    val startActivityIntent = Intent.makeMainActivity(
        ComponentName(
            ApplicationProvider.getApplicationContext(),
            HiltTestActivity::class.java
        )
    ).putExtra(FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY, themeResId)

    ActivityScenario.launch<HiltTestActivity>(startActivityIntent).onActivity { activity ->
        val fragment: Fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
            Preconditions.checkNotNull(T::class.java.classLoader),
            T::class.java.name
        ).apply {
            arguments = fragmentArgs
        }
        activity.supportFragmentManager.beginTransaction()
            .add(android.R.id.content, fragment, "")
            .commitNow()
        (fragment as T).action()
    }
}

The key here is that the Fragment is added to a Hilt-aware activity, which triggers the @AndroidEntryPoint injection pipeline.

Step 2: Confirm Your Dependency Setup

Double-check your Gradle configuration to ensure all Hilt and Robolectric dependencies are aligned and properly configured:

  1. Project-level build.gradle:
    plugins {
        id 'com.google.dagger.hilt.android' version '2.44' apply false
        // Other plugins...
    }
    
  2. App-level build.gradle:
    plugins {
        id 'com.google.dagger.hilt.android'
        // Other plugins...
    }
    
    android {
        testOptions {
            unitTests {
                includeAndroidResources = true
            }
        }
    }
    
    dependencies {
        // Hilt core
        implementation 'com.google.dagger:hilt-android:2.44'
        kapt 'com.google.dagger:hilt-compiler:2.44'
    
        // Testing dependencies
        testImplementation 'org.robolectric:robolectric:4.12.1'
        testImplementation 'com.google.dagger:hilt-android-testing:2.44'
        kaptTest 'com.google.dagger:hilt-compiler:2.44'
        // Other test dependencies...
    }
    
    hilt {
        enableTransformForLocalTests = true
    }
    

Ensure all Hilt versions match, and Robolectric uses a version compatible with your Hilt setup.

Step 3: Validate Your Injectable Class

Make sure TestClass is properly configured for Hilt injection. Either use an @Inject constructor:

class TestClass @Inject constructor() {
    fun some() { /* Your implementation */ }
}

Or provide it via a Hilt module if it requires external dependencies:

@Module
@InstallIn(FragmentComponent::class)
object TestModule {
    @Provides
    fun provideTestClass(): TestClass = TestClass()
}

Without this, Hilt has no way to resolve the dependency for your Fragment.

Step 4: Adjust Fragment Lifecycle Access (If Needed)

Robolectric's Fragment lifecycle execution can differ slightly from real devices. Try moving the testClass.some() call into the launchFragmentInHiltContainer action block instead of onCreate:

@Test
fun checkFragmentProperty() {
    launchFragmentInHiltContainer<TestFragment> { 
        testClass.some() // Access the injected field here
    }
}

This ensures the Fragment is fully attached and injected before you access the lateinit property.

Step 5: Clean and Rebuild

Sometimes Hilt's annotation processor cache can cause issues. Run:

./gradlew clean

Then rebuild your project and re-run the test.


内容的提问来源于stack exchange,提问作者lukjar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:02:47