Mockito-Kotlin如何mock入参出参为String的接口并避免重复stub?
方案1:使用通用参数匹配实现批量打桩
不管你用的是MockK还是Mockito框架,都可以通过匹配任意key参数,结合预定义的映射表实现一次打桩覆盖所有取值场景,不需要逐key写规则。
以MockK为例的写法:
// 预定义需要的键值对 val stringMap = mapOf( "key1" to "Value 1", "key2" to "Value 2", "key3" to "Value 3" ) // 一次性完成所有key的打桩 private val stringProvider = mock<StringProvider> { // 匹配任意传入的key,从map里取值返回,没有匹配的可以返回默认值或者抛异常 on { get(any()) } answers { stringMap.getOrDefault(firstArg(), "default_value") } }
如果用Mockito的话写法如下:
val stringMap = mapOf( "key1" to "Value 1", "key2" to "Value 2" ) private val stringProvider = mock(StringProvider::class.java) `when`(stringProvider.get(anyString())).thenAnswer { invocation -> stringMap.getOrDefault(invocation.getArgument(0), "default_value") }
方案2:封装通用工具函数复用打桩逻辑
可以把上述逻辑封装成全局通用的工具方法,所有测试类需要用到StringProvider mock的时候直接调用即可,不需要重复写打桩代码:
// 放在测试通用工具类里 fun mockStringProvider(keyValues: Map<String, String>, defaultValue: String = ""): StringProvider { return mock { on { get(any()) } answers { keyValues.getOrDefault(firstArg(), defaultValue) } } } // 测试类里直接使用 private val stringProvider = mockStringProvider( mapOf( "key1" to "Value 1", "key2" to "Value 2" ), defaultValue = "未匹配的key默认值" )
方案3:使用测试假实现(Test Fake)替代Mock
如果大量测试场景都需要用到StringProvider,直接写一个测试用的假实现比mock框架更轻量、更易维护,不需要任何打桩操作:
// 放在测试通用代码目录 class FakeStringProvider( private val values: MutableMap<String, String> = mutableMapOf(), private val defaultValue: String = "" ) : StringProvider { override operator fun get(key: String): String { return values.getOrDefault(key, defaultValue) } // 支持测试过程中动态添加/修改键值对 fun put(key: String, value: String) { values[key] = value } } // 测试类里直接使用 private val stringProvider = FakeStringProvider( values = mapOf("key1" to "Value 1", "key2" to "Value 2"), defaultValue = "test_default" ) // 测试过程中需要动态改值直接调用put即可 stringProvider.put("new_key", "new_value")
这种方案完全不依赖Mock框架,性能更好,也不会出现mock框架的各类匹配规则冲突问题。
内容的提问来源于stack exchange,提问作者StuartDTO
相关产品推荐
相关产品推荐

