java .lang.RuntimeException: невозможно создать экземпляр класса ViewModel в модульном тесте - PullRequest
1 голос
/ 09 июля 2020

Я использую рукоять кинжала с интегрированной рукоятью реактивного ранца

Мои производственные зависимости

implementation "com.google.dagger:dagger:2.28"
kapt "com.google.dagger:dagger-compiler:2.28"

implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'

implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"

Мои тестовые зависимости

testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"

testImplementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kaptTest 'androidx.hilt:hilt-compiler:1.0.0-alpha01'

Теперь в своей деятельности я использую by viewModels() расширенную форму реактивного ранца

private val viewModel: SplashViewModel by viewModels()

И в моей модели ViewModel я использую @ViewModelInject из реактивного ранца

class SplashViewModel @ViewModelInject constructor(
    private val authenticationRepository: AuthenticationRepository
)

Он отлично работает в производственном коде, но при запуске действия из теста с использованием Robolectri c приложение обнаружит sh с этим исключением

java.lang.RuntimeException: Cannot create an instance of class com.example.SplashViewModel

Это мой тестовый класс

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1], application = TestApplication::class)
@HiltAndroidTest
class SplashActivityTest {

    private val authenticationRepository: AuthenticationRepository = mockk(relaxed = true)

    @get:Rule
    val rule = HiltAndroidRule(this)

    @get:Rule
    var activityRule = IntentsTestRule(SplashActivity::class.java)
}

А это мой TestApplication класс

class TestApplication : MultiDexApplication(), GeneratedComponentManager<Any>,
    TestApplicationComponentManagerHolder {

    private var componentManager: TestApplicationComponentManager? = null

    override fun onCreate() {
        super.onCreate()
        JodaTimeAndroid.init(this)
    }

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        componentManager = TestApplicationComponentManager(this)
    }

    override fun componentManager(): Any? {
        return componentManager
    }

    override fun generatedComponent(): Any {
        return componentManager!!.generatedComponent()
    }
}

1 Ответ

0 голосов
/ 05 сентября 2020

Проблема в том, что при запуске Activity из тестового примера это «нормальное» Activity, а не Hilt Activity, помеченное @AndroidEntryPoint.

Для решения этой проблемы вам необходимо (1 ) создайте @AndroidEntryPoint Activity, которое вы запускаете, (2) создайте сценарий отладки для этого.

Вот простое руководство для всего, что вам нужно: https://www.youtube.com/watch?v=k4zG93ogWFY&t и https://www.youtube.com/watch?v=B-dJTFeOAqw&t

...