Spring环境下测试Kotlin扩展函数如何Mock返回模拟服务实例
扩展函数Mock实现方案(MockK + Mockito 两种版本)
1. MockK 实现(更推荐Kotlin项目使用)
Kotlin顶层扩展函数编译后对应ExtensionsKt类的静态方法,MockK直接mock该静态类即可:
- 修正后的mock写法:
// 替换成你Extensions.kt文件实际的全类名路径 mockkStatic("com.your.business.path.ExtensionsKt") // 准备你要返回的mock service实例 val mockService = mockk<BasicService<*>>() // 匹配所有List<BasicService>调用该扩展方法的场景,任意customer参数都返回mock实例 every { any<List<BasicService<*>>>().getServiceByCustomer(anyString()) } returns mockService // 如果需要匹配特定customer,把anyString()换成指定字符串即可 // every { any<List<BasicService<*>>>().getServiceByCustomer("test_customer") } returns mockService
- 测试结束后记得释放静态mock,避免影响其他用例:
afterEach { unmockkStatic("com.your.business.path.ExtensionsKt") }
你之前写法的问题:
- 没有传入
customer参数,方法签名匹配失败 - 固定了调用方法的List对象为
listOf(service),和控制器中注入的services不是同一个实例,无法匹配触发mock逻辑
2. Mockito(com.nhaarman.mockitokotlin2)实现
Mockito需要先引入mockito-inline依赖才能支持静态/顶层函数mock,实现方式如下:
// 准备mock service实例 val mockService = mock<BasicService<*>>() // mock扩展函数对应的静态类,使用try-with-resources自动释放,避免影响其他用例 mockStatic(ExtensionsKt::class.java).use { mockedStatic -> // 扩展函数编译后第一个参数为接收者对象,所以需要传入List实例作为第一个参数 `when`( ExtensionsKt.getServiceByCustomer(any<List<BasicService<*>>>(), anyString()) ).thenReturn(mockService) // 在这里编写你的控制器测试逻辑 }
内容的提问来源于stack exchange,提问作者jwsinner
相关产品推荐
相关产品推荐

