Hey I am experiencing a serious issue - it looks like mocking answer for a parametrised suspended me...
i
Hey I am experiencing a serious issue - it looks like mocking answer for a parametrised suspended method does not work as expected:
Copy code
class ExampleUnitTest {
    private val repository = mockk<AlbumRepository>()

    private val cut = GetAlbumUseCase(repository)

    @Test
    fun `when execute return success`() {
        // given
        val albumName = "Thriller"
        val artistName = "Michael Jackson"
        val mbId = "123"

        // when
        val actual = runBlocking { cut.execute(albumName, artistName, mbId) }

        // then

    }
}
Copy code
no answer found for: AlbumRepository(#1).getAlbumInfo(Thriller, Michael Jackson, 123, continuation {})
io.mockk.MockKException: no answer found for: AlbumRepository(#1).getAlbumInfo(Thriller, Michael Jackson, 123, continuation {})
	at app//io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:93)
The answer can't be found (most likely due to
continuation {}
param). I have crafted a sample project to reproduce this. Steps: 1. Open project using
Android Studio
2. Run
ExampleUnitTest
tests Can someone take a look? Is there any workaround?
c
in your example there is no answer configured and also the mock is not relaxed.
shouldnt the exception also show what answers it has configured?
i
I was stripping more advanced example and I have stripped it too much - here is the test with answer that also fails in the same way
Copy code
class ExampleUnitTest {
    private val repository = mockk<AlbumRepository>()

    private val cut = GetAlbumUseCase(repository)

    @Test
    fun `when execute return success`() {
        // given
        val albumName = "Thriller"
        val artistName = "Michael Jackson"
        val mbId = "123"

        coEvery { repository.getAlbumInfo(artistName, albumName, mbId) } answers { mockk() }

        // when
        val actual = runBlocking { cut.execute(albumName, artistName, mbId) }

        // then
    }
}
and class under test
Copy code
internal class GetAlbumUseCase(
    private val albumRepository: AlbumRepository,
) {

    sealed interface Result {
        data class Success(val data: String) : Result
        data class Error(val e: Throwable) : Result
    }

    suspend fun execute(
        artistName: String,
        albumName: String,
        mbId: String?,
    ): Result {
        val data = albumRepository.getAlbumInfo(artistName, albumName, mbId)
        return Result.Success(data)
    }
}
c
does it work when you change it to
.returns(mockk())
i
You can't mock a String really, but this also fails with the same exception
Copy code
coEvery { repository.getAlbumInfo(artistName, albumName, mbId) } returns "ssasa"
Changing definition of repository mock to relaxed works
Copy code
private val repository = mockk<AlbumRepository>(relaxed = true)
but relaxing mock only because coroutines are used seems a bit off
As expected result is incorrect test:
Copy code
class ExampleUnitTest {
    private val repository = mockk<AlbumRepository>(relaxed = true)

    private val cut = GetAlbumUseCase(repository)

    @Test
    fun `when execute return success`() {
        // given
        val albumName = "Thriller"
        val artistName = "Michael Jackson"
        val mbId = "123"

        coEvery { repository.getAlbumInfo(artistName, albumName, mbId) } returns "ssasa"

        // when
        val actual = runBlocking { cut.execute(albumName, artistName, mbId) }

        // then
        assertEquals(GetAlbumUseCase.Result.Success("ssasa"), actual)
    }
}
Result
Copy code
Expected :Success(data=ssasa)
Actual   :Success(data=)
<Click to see difference>
Tested class (no changes)
Am I missing something else or does the mockk can correctly provide the answer after all?
c
what i find suprising is that the exception does not contain the configured answers of the mock. I think it should
one thing you could is look at the mockk test suite and check if that case is tested (i really thin it is or should be) and if its not try to reproduce your error in a test case
n
Did you find an answer to this ? @igor.wojda I am having same problem. When mocking suspend functions it expects continuation
i
I have no answer yet, unfortunately.
I have created a new issue - please put more input if you can https://github.com/mockk/mockk/issues/957
5707 Views