Kotlin中如何对作为方法入参的回调函数进行单元测试
解决方案
第一步:修复业务代码语法错误
当前ClassA中的getReadyCallback方法未声明返回值类型,Kotlin默认返回Unit,会导致传入clientProvider.create的参数类型不匹配,先修正:
// 修正后写法 private fun getReadyCallback(): ReadyCallback { return ReadyCallback { onReady() } } // 也可简化为单表达式写法 private fun getReadyCallback(): ReadyCallback = ReadyCallback { onReady() }
第二步:用参数捕获器实现测试逻辑
不需要mock私有方法,直接通过Mockito的ArgumentCaptor参数捕获功能,拿到clientProvider.create接收的ReadyCallback实例,主动触发回调即可验证逻辑,完整测试代码如下:
import com.nhaarman.mockitokotlin2.* import org.junit.Before import org.junit.Test class ClassATest { private lateinit var unitUnderTest: ClassA private val clientProviderMock: ClassB = mock() private val classCMock: ClassC = mock() private val classDMock: ClassD = mock() private val clientMock: ClassD = mock() @Before fun setup() { unitUnderTest = ClassA( clientProvider = clientProviderMock, classC = classCMock, classD = classDMock ) whenever(clientProviderMock.create(any())).thenReturn(clientMock) } @Test fun `就绪状态触发时调用classC的otherMethod`() { // 触发客户端创建 unitUnderTest.createClient() // 捕获传入clientProvider.create的ReadyCallback参数 val callbackCaptor = argumentCaptor<ReadyCallback>() verify(clientProviderMock).create(callbackCaptor.capture()) val capturedCallback = callbackCaptor.firstValue // 主动触发就绪回调 capturedCallback.onReady() // 验证otherMethod被调用 verify(classCMock).otherMethod() } @Test fun `未触发就绪状态时不调用classC的otherMethod`() { // 仅触发客户端创建,不主动调用回调 unitUnderTest.createClient() // 验证没有和classC产生任何交互 verifyZeroInteractions(classCMock) } }
实现说明
argumentCaptor可以捕获mock对象方法调用时传入的实参,不需要访问被测类的私有方法,完全从外部行为切入验证,符合单元测试最佳实践。两个测试用例分别覆盖了就绪、未就绪两种场景,完全匹配你的验证需求。
内容的提问来源于stack exchange,提问作者peanutnut
相关产品推荐
相关产品推荐

