0

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?

Buddy Christ
  • 1,364
  • 8
  • 22
Darri
  • 3
  • 2

1 Answers1

2

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)
                }
        }
    }
}
Salomon BRYS
  • 9,247
  • 5
  • 29
  • 44