如何在Kotlin单元测试中Stub map扩展函数?求解决方案
解决思路
你当前写法的核心问题是:Stub的是map {}(空lambda参数的map调用),但实际业务代码里的map用的是带具体逻辑的lambda(比如调用了mappingSectionsToRecordedExerciseDataModels方法)。Mockito会将不同lambda视为不同参数,因此匹配不到你预设的Stub结果,才会抛出no answer found错误。
给你几个可行的解决方向:
方向1:Stub转换逻辑而非map函数
如果你的map内部是调用某个转换函数(比如错误信息里的mappingSectionsToRecordedExerciseDataModels),直接Stub这个转换函数更简单:
- 先让
trainWorkoutResult.exerciseSections返回包含mock对象的真实列表:val mockSection = mock<ExerciseSection>() whenever(trainWorkoutResult.exerciseSections).thenReturn(listOf(mockSection)) - 然后Stub转换函数的返回值:
whenever(legacyDataMapper.mappingSectionsToRecordedExerciseDataModels(mockSection)) .thenReturn(mockRecordedModel)
真实的map函数会自动遍历列表,调用Stub好的转换函数得到预期结果,完全不需要Stubmap本身。
方向2:匹配任意lambda来Stub map函数
如果确实需要直接Stubmap的返回结果,可以用Mockito匹配器匹配任意lambda参数:
// 需要导入org.mockito.kotlin.any whenever(trainWorkoutResult.exerciseSections.map(any())).thenReturn(trainSections)
这种方式会匹配该列表上所有的map调用,无论传入什么lambda,都会返回你指定的trainSections。
方向3:封装map逻辑到可测试的函数
把map的逻辑抽成单独的成员函数,比如:
class YourClass(private val mapper: LegacyDataMapper) { fun processSections(sections: List<ExerciseSection>): List<RecordedExerciseDataModel> { return sections.map { mapper.mappingSectionsToRecordedExerciseDataModels(it) } } }
然后在测试里直接Stub这个processSections函数,相比Stub扩展函数更清晰可控。
内容的提问来源于stack exchange,提问作者kokoko
相关产品推荐
相关产品推荐

