如何使用Kotest和Mockk正确验证函数是否被另一个函数调用
完善Processor类的Kotlin测试代码
以下是针对两个测试需求的完整测试实现,基于mockk和BehaviorSpec的测试风格:
测试场景1:验证subscribe方法的调用逻辑
需要确认调用underTest.subscribe()时,subscription.subscribe("n-m-events", ::process)被正确触发。
测试场景2:验证process方法的完整逻辑
原测试已覆盖service.process(msg)的验证,现在补充connection.publish(...)的验证,确保两个方法都按预期被调用。
完整测试代码
class ProcessorTest : BehaviorSpec({ val subscription = mockk<Subscription>() val service = mockk<Service>() val connection = mockk<Connection>() val msg = mockk<DecodedMessage>() val headers = mockk<Headers>() // 新增Headers的mock,支持replyTo逻辑 val underTest = Processor( subscription, service ) // 测试subscribe方法 Given("subscription initialization") { When("subscribe() is invoked on Processor") { underTest.subscribe() Then("subscription should register with correct subject and handler") { verify(exactly = 1) { subscription.subscribe("n-m-events", underTest::process) } } } } // 测试process方法 Given("message processing flow") { val testReplyTo = "test-reply-subject-456" // Mock所有依赖的行为 every { service.process(msg) } just runs every { msg.headers } returns headers every { headers.replyToOrThrow() } returns testReplyTo every { connection.publish(eq(testReplyTo), eq("ok".toByteArray(Charsets.UTF_8))) } just runs When("process() is called with message and connection") { underTest.process(msg, connection) Then("service processes the message and connection sends ok reply") { verify(exactly = 1) { service.process(msg) } verify(exactly = 1) { connection.publish(testReplyTo, "ok".toByteArray(Charsets.UTF_8)) } } } } })
关键实现说明
- subscribe测试:直接调用目标方法后,通过
verify断言subscription.subscribe以正确的主题和处理器方法被调用一次 - process测试:
- 新增
Headers的mock,确保msg.headers.replyToOrThrow()能返回预设的测试值 - 明确mock
connection.publish的预期参数,避免模糊匹配 - 同时验证
service.process和connection.publish的调用行为,覆盖process方法的完整逻辑
- 新增
内容的提问来源于stack exchange,提问作者Dave Whyte
相关产品推荐
相关产品推荐

