How to mock a method with context receiver? Here's...
# mockk
d
How to mock a method with context receiver? Here's my setup:
Copy code
interface AProvider {
    context(ContextProvider)
    fun getA(a: String) = a
}

class ContextProvider

inline fun <reified T : Any> mockkWithContext(noinline block: context(ContextProvider) T.() -> Unit) =
    withContext { mockk<T> { block(this@withContext, this@mockk) } }

fun <T> withContext(block: ContextProvider.() -> T) = ContextProvider().block()

class ContextReceiversTest {
    @Test
    fun `a test`() {
        val aProviderMock: AProvider = mockkWithContext {
            every { getA(any()) } answers { firstArg() }
        }
        println(withContext { aProviderMock.getA("a") })
    }
}
As you can see the getA method has
ContextProvider
as a receiver. In order to mock it in the test I have to wrap standard
mockk
in
withContext
which provides the required receiver for
getA
. If I run the test, though, it fails on
Copy code
io.mockk.MockKException: no answer found for: AProvider(#1).getA(com.example.playground.ContextProvider@38b5f25, a)
Apparently mockk expects the receiver as the first argument but obviously I cannot write
every { getA(any(), any()) }
. So my question is how can I mock the method in my case?
a
I suspect MockK just can’t support context receivers without a good amount of work, which hasn’t been started. The insertion of an additional parameter is similar to how
suspend fun
works, and MockK provides specific functions for mocking those. Supporting context receivers will probably be similar. I wonder, what happens if you try
coEvery { getA(any()) }
? If you need something that works right now, then you could try manually mock by creating an object that implements
AProvider
Copy code
fun mockAProvider() = object : AProvider { 
  context(ContextProvider)
  override fun getA(a: String) = "stubbed response"
 }
d
coEvery
doesn't work and the object workaround is probably applicable only in simple cases (not what I have in reality). I didn't see context-receivers related MockK issue so I will file one.
810 Views