I want to override a Kodein binding by a mock before testing my class.
There is my Kodein init:
val kodein = Kodein {
bind<MyRepository>() with provider { MyRepository() }
}
Then my class to test:
class MyClass {
private val mMyRepository: MyRepository by kodein.instance()
suspend fun sendData() = mMyRepository.sendData()
}
And my test 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)
}
}
}
}
I want to override mMyRepository
value in MyClass
during my test by mMyRepositoryMock
.
Can somebody help me doing it?
This is precisely why we do not recommend using a global Kodein instance.
The best way to ensure a class testability is to remove its context dependency.
Consider the following class:
class MyClass(override val kodein: Kodein) {
private val mMyRepository: MyRepository by kodein.instance()
suspend fun sendData() = mMyRepository.sendData()
}
Now the kodein
it uses is passed as parameter, and can therefore be properly configured for tests:
@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)
}
}
}
}