2

I have an extension function for interface like the following:

import javax.jms.ConnectionFactory

fun ConnectionFactory.foo() {
    println("do some stuff")
}

How can I mock the function foo?

Please note, I have seen approaches for classes and objects in http://mockk.io/#extension-functions, but it does not work. I have tried this one:

import io.mockk.classMockk
import io.mockk.every
import org.junit.Test
import javax.jms.ConnectionFactory

class ExtensionFunctionTest {
@Test
fun mockExtensionFunction() {
    val connectionFactory = classMockk(ConnectionFactory::class)
    every { connectionFactory.foo() } returns println("do other stuff")
    connectionFactory.foo()
}
}

It throws exception:

io.mockk.MockKException: Missing calls inside every { ... } block.
NameAlex
  • 163
  • 1
  • 3
  • 10
  • what's the file name from where your extension function is? Is this the full verifiable example, or is the class different? – LeoColman Apr 25 '18 at 14:10
  • The function is defined outside of the class ConnectionFactory and is module wide. – NameAlex Apr 26 '18 at 20:37

1 Answers1

4

According to the documentation in case of module wide extension functions you need to staticMock "hidden" class created for an extension function. Here is an example (assuming the file name is com/sample/extmockingtest/SampleTest.kt):

fun <T> Iterable<T>.foo(): String  = "do some stuff"

class ExtensionFunctionTest {
    @Test
    fun mockExtensionFunction() {
        val itMock = classMockk(Iterable::class);
        staticMockk("com.sample.extmockingtest.SampleTestKt").use {
            every {
                itMock.foo()
            } returns "do other stuff"

            assertEquals("do other stuff", itMock.foo())

            verify {
                itMock.foo()
            }
        }
    }
}
  • Here is the defined implementation of the interface `listOf(1, 2, 3)`, but can we mock on an interface, like `Iterable.foo()` ? – NameAlex Apr 26 '18 at 20:42
  • Sure, we may replace `listOf()` with `val itMock = classMockk(Iterable::class)`. Then we can use this mock inside `every` and `verify`. I've updated original code example to cover this case. – Roman Safronov Apr 26 '18 at 21:13