【问题标题】:java.lang.RuntimeException: Cannot create an instance of class ViewModel in unit testjava.lang.RuntimeException:无法在单元测试中创建类 ViewModel 的实例
【发布时间】:2020-07-09 15:23:13
【问题描述】:

我正在使用匕首与刀柄喷气背包集成

我的生产依赖项

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'

现在在我的 Activity 中,我使用的是 by viewModels() 扩展表单 jetpack

private val viewModel: SplashViewModel by viewModels()

在我的 ViewModel 中,我使用的是来自 jetpack 的 @ViewModelInject

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

它在生产代码中运行良好,但是当使用 Robolectric 从测试中启动 Activity 时,应用会因此异常而崩溃

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()
    }
}

【问题讨论】:

    标签: android kotlin dagger dagger-hilt


    【解决方案1】:

    问题在于,从测试用例启动 Activity 时,它是“正常”Activity,而不是带有 @AndroidEntryPoint 注释的 Hilt Activity。

    为了解决这个问题,您必须 (1) 创建一个您启动的 @AndroidEntryPoint Activity,(2) 为此创建调试场景。

    这里有一个简单的教程,可以满足您的所有需求:https://www.youtube.com/watch?v=k4zG93ogWFY&thttps://www.youtube.com/watch?v=B-dJTFeOAqw&t

    【讨论】:

      【解决方案2】:

      使用 public 来声明 SplashViewModel 类,如

      public class SplashViewModel extends ViewModel {
          // TODO: Implement the ViewModel
      }
      

      【讨论】:

      • 它已经公开了,我使用的是 Kotlin 而不是 Java。在 Kotlin 中,所有类默认都是公开的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      • 2020-03-30
      • 1970-01-01
      • 2021-11-28
      • 2017-12-13
      相关资源
      最近更新 更多