AndroidTest 的可待因覆盖绑定

Kodein override binding for AndroidTest

我想在测试我的 class 之前通过模拟覆盖 Kodein 绑定。

这是我的 Kodein 初始化:

val kodein = Kodein {
    bind<MyRepository>() with provider { MyRepository() }
}

然后我的class要测试:

class MyClass {
    private val mMyRepository: MyRepository by kodein.instance()

    suspend fun sendData() = mMyRepository.sendData()
}

还有我的测试class:

@RunWith(AndroidJUnit4::class)
class MyClassTest {

    @MockK
    lateinit var mMyRepositoryMock: MyRepository

    val mMyClass = MyClass()

    @Before
    fun setUp() {
        MockKAnnotations.init(this, relaxUnitFun = true)
    }

    @Test
    fun testSendData() {
        coEvery { mMyRepositoryMock.sendData() } returns Unit

        runBlocking {
            mMyClass.sendData()
                .collect {
                    assertTrue(true)
                }
        }
    }
}

我想在 mMyRepositoryMock 测试期间覆盖 MyClass 中的 mMyRepository 值。

有人可以帮我做吗?

这正是我们推荐使用全局 Kodein 实例的原因。

确保 class 可测试性的最佳方法是移除其上下文依赖性。

考虑以下 class:

class MyClass(override val kodein: Kodein) {
    private val mMyRepository: MyRepository by kodein.instance()

    suspend fun sendData() = mMyRepository.sendData()
}

现在它使用的 kodein 作为参数传递,因此可以为测试正确配置:

@RunWith(AndroidJUnit4::class)
class MyClassTest {

    @MockK
    lateinit var mMyRepositoryMock: MyRepository

    val kodein by Kodein.lazy {
        bind<MyRepository>() with provider { mMyRepositoryMock }
    }

    val mMyClass by lazy { MyClass(kodein) }

    @Before
    fun setUp() {
        MockKAnnotations.init(this, relaxUnitFun = true)
    }

    @Test
    fun testSendData() {
        coEvery { mMyRepositoryMock.sendData() } returns Unit

        runBlocking {
            mMyClass.sendData()
                .collect {
                    assertTrue(true)
                }
        }
    }
}