首页 > 解决方案 > 用于 AndroidTest 的 Kodein 覆盖绑定

问题描述

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

有我的 Kodein init:

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

然后我的课要测试:

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

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

还有我的测试课:

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

我想mMyRepositoryMyClass测试期间通过mMyRepositoryMock.

有人可以帮我做吗?

标签: androidkotlinjunitkodein

解决方案


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

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

考虑以下类:

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

推荐阅读