kotlin 在UnitTest / hilt中获取视图模型

hrirmatl  于 2023-03-30  发布在  Kotlin
关注(0)|答案(1)|浏览(110)

我想在我的@Inject构造函数(/* injects */)中获得我的ViewModel,但我不知道如何做到这一点。x1c 0d1x
禁止用anotation注入它,但我也不能使用“by viewModels”,因为我不在一个片段中...

um6iljoc

um6iljoc1#

不建议使用依赖项注入进行单元测试,因为这与单元测试的目的相悖。
单元测试的想法是隔离调用者所消耗的将返回或导致预期结果的条件。这意味着应该控制视图模型的依赖关系,以Assert在某些条件下,预期会发生某些事情。类似于这样:

class SomeVieModel(dependency: Dependency) {
 
    doSomething(): Int {
        return dependency.something()
    }

}

测试视图模型返回的值是否与依赖项相同

val controlledDepedency = //some way to have a controlled depencey
//make the controlledDepedency always returns 1

val obtained = viewModel.doSomething()

assertEquals(1, obtained)

最常见的方法是使用模拟。对于Android,最常见的库是Mockito和Mockk。这两个库都允许您使用存根并配置行为。
但是还有其他的mocking技术,例如:伪装或假人
如果这样做,你有Android原生API的问题,一个常见的解决方案是使用Roboelectric。例如,如果你的视图模型得到一个颜色ContextCompat.getColor,将返回null在单元测试,使您的测试失败。Roboelectric,照顾这一点。
针对该问题另一种解决方案是抽象:

interface AndroidAbstraction {

    //cant remember the annotation for a resolved color
    fun colorLambda(@ColorRes color: Int) : Int

}

因此,您可以将AndroidAbstraction实现传递给DI:

class AndroidAbstractionImplementation(context: Context) {

    fun colorLambda(@ColorRes color: Int) = ContextCompat.getColot(context, color)

}

在视图模型中使用它

class SomeVieModel(
    dependency: Dependency,
    androidAbstraction: AndroidAbstraction
) {

    //now you can call androidAbstraction.colorLambda(...)

}

然后将其作为受控依赖项(例如mock)传递给单元测试。

相关问题