Mockk added support for mocking global functions.
However, when they have overloads there's a problem.
For example if you try to mock delay()
with mockkStatic(::delay)
you encounter this error:
Overload resolution ambiguity:
public suspend fun delay(timeMillis: Long): Unit defined in kotlinx.coroutines
public suspend fun delay(duration: Duration): Unit defined in kotlinx.coroutines
Is there a way to mock a global function that has overloads?
That one is a bit tricky, because it seems to be impossible to access the declaring class of such a global function using Kotlin reflection. However, it is possible to use Java reflection, if you know at least one other function in the same file that is not overloaded.
Let's for instance assume that you mean delay
of coroutines, there is the function awaitCancellation
defined in the same file.
We can use that to access the Java class that declares delay
and query it for the right implementation of delay
:
val declaringClass = ::awaitCancellation.javaMethod!!.declaringClass
val methods = declaringClass.declaredMethods
val ref = methods.mapNotNull { it.kotlinFunction }
.filter { it.name == "delay" }
.first { it.parameters[0].type == Long::class.createType() }
mockkStatic(ref)
In this example, ref
points to the implementation of delay
that takes a Long
as parameter.
For the other implementation we would need to replace Long
with Duration
in the last condition.