如何Mock Kotlin中接口的扩展函数?
Mocking a Kotlin Extension Function on ConnectionFactory with MockK
我懂你碰到的这个坑——Kotlin扩展函数的本质其实是编译成静态方法的,所以直接用classMockk根本碰不到这个函数的实现,自然Mock无效。结合你的代码场景,给你一套能跑通的解决方案:
核心原理
你的foo()是顶级扩展函数(没放在任何类内部),Kotlin会把这类函数编译成一个名为[你的文件名]Kt的Java静态类。要Mock它,就得针对这个生成的静态类下手,用MockK的mockkStatic方法。
具体步骤&完整代码
假设你的扩展函数写在JmsExtensions.kt文件里:
// JmsExtensions.kt import javax.jms.ConnectionFactory fun ConnectionFactory.foo() { println("do some stuff") }
对应的测试代码应该这么写:
import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic import io.mockk.verify import org.junit.Test import javax.jms.ConnectionFactory class ExtensionFunctionTest { @Test fun mockExtensionFunction() { // 1. 先Mock ConnectionFactory的实例 val factoryMock = mockk<ConnectionFactory>() // 2. 关键:Mock扩展函数所在的静态类(文件名+Kt) // 注意这里要写全限定类名,比如你的文件在com.example包下,就是com.example.JmsExtensionsKt mockkStatic("com.example.JmsExtensionsKt") // 3. 定义扩展函数的Mock行为 every { factoryMock.foo() } returns Unit // 如果想模拟异常,可以写成:every { factoryMock.foo() } throws RuntimeException("Mocked error") // 4. 调用扩展函数 factoryMock.foo() // 5. 验证函数确实被调用了 verify { factoryMock.foo() } } }
为什么你之前的方法无效?
你用classMockk<ConnectionFactory>()是在MockConnectionFactory这个类本身,但扩展函数并不属于这个类的成员——它是独立的静态方法,所以Mock类本身完全影响不到扩展函数的执行逻辑。只有把生成的xxxKt静态类Mock掉,才能接管扩展函数的行为。
如果你的扩展函数是定义在某个类内部的成员扩展,那方法会略有不同,但根据你给出的代码,显然是顶级扩展,上面的方案完全适用。
内容的提问来源于stack exchange,提问作者NameAlex
相关产品推荐
相关产品推荐

