Skip to content

MockK: Mocking Repository in the presenter class

Devrath edited this page Mar 2, 2024 · 2 revisions

Scenario

  • Here we have a presenter class that gets data from a repository.
  • Data received from the presenter is then used to do some tasks.
  • So we need to write some test cases in the presenter class.
  • We can use MockK to mock the repository in the presenter class.

Code

MainContract.kt

interface MainContract {

    interface Presenter {
        fun fetchData()
    }

    interface View {
        fun onResult(result: List<String>)
        fun onError(error: Throwable)
    }

}

DataModel.kt

data class DataModel(val dataIndex : Int, val dataValue: String)

DataRepository.kt

class DataRepository {
    fun fetchData(): List<DataModel> {
        return listOf(
            DataModel(1, "Value 1"), DataModel(2, "Value 2"),
            DataModel(3, "Value 3"), DataModel(4, "Value 4"))
    }
}

MainPresenter.kt

class MainPresenter(
    private val view: MainContract.View,
    private val dataRepository: DataRepository
) : MainContract.Presenter {

    override fun fetchData() {
        try {
            val result = dataRepository.fetchData()

            view.onResult(
                result.map { it.dataValue }
            )
        } catch (err: Exception) {
            view.onError(err)
        }
    }
}

TestCase

class MainPresenterTest {

    // View linked - Interface
    @RelaxedMockK
    lateinit var view: MainContract.View

    @RelaxedMockK
    lateinit var dataRepository: DataRepository

    // Presenter linked - Interface
    private lateinit var mainPresenter: MainContract.Presenter

    @Before
    fun setUp() {
        // Initialized the mockK
        MockKAnnotations.init(this)
        // Initialized the presenter class
        mainPresenter = MainPresenter(view,dataRepository)
    }

    @After
    fun tearDown() {
        unmockkAll()
    }

    @Test
    fun `test fetch data with an empty list`() {
        // We have mocked the repository so data from teh repository is available
        every { dataRepository.fetchData() } returns listOf()
        // Initiate fetching of data: ---> At this moment the presenter instance will contain the data mocked
        mainPresenter.fetchData()

        // We shall use slot reference to get the data inside the interface
        val captureData = slot<List<DataModel>>()
        // Check that it is called only once --> Also pass the Capture Slot
        verify(exactly = 1) { view.onResult(capture(captureData)) }

        // Perform assertion
        captureData.captured.let { res ->
            assertNotNull(res)
            assert(res.isEmpty())
        }
    }



}
Clone this wiki locally