You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Mockito Mock带Raise<BusinessError>上下文接收器服务返回null问题

Mockito Mock带上下文接收器方法返回Null的解决方案

问题背景

测试依赖ServiceTwo的ServiceOne服务时,ServiceTwo的call方法带有Raise<BusinessError>上下文接收器。使用Mockito mock ServiceTwo后,测试代码中直接调用mock的call方法能返回预期值,但ServiceOne内部调用该mock方法却返回null。原因是mock设置时的either上下文与ServiceOne内部的either上下文不是同一个实例,导致Mockito的参数匹配失败。

可行解决方案

方案1:调整Mockito的参数匹配规则

Mockito会将Kotlin的上下文接收器编译为方法的第一个隐式参数,因此需要显式匹配这个上下文参数,允许任意Raise实例触发mock返回值。

修改后的测试代码:

class ServiceOneTests {
    @Test
    fun `should return the correct aggregation result`() {
        val serviceTwo = mock(ServiceTwo::class.java)
        val serviceOne = ServiceOne(serviceTwo)
        
        // 用any()匹配任意Raise上下文实例,eq("1")匹配指定参数
        `when`(serviceTwo.call(any<Raise<BusinessError>>(), eq("1"))).thenReturn("1")
        
        val result = either {
            val mockResult = serviceTwo.call("1")
            assertEquals("1", mockResult)
            serviceOne.call("1")
        }
        
        when(result) {
            is Either.Left -> fail()
            is Either.Right -> assertEquals("1", result.value)
        }
    }
}

方案2:改用MockK(推荐)

MockK是Kotlin专用的Mock库,对上下文接收器、协程等Kotlin特性支持更原生,无需处理编译后的参数转换逻辑。

  1. 先添加MockK依赖(以Gradle为例):
testImplementation "io.mockk:mockk:1.13.8"
  1. 修改后的测试代码:
import io.mockk.every
import io.mockk.mockk
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.fail

class ServiceOneTests {
    @Test
    fun `should return the correct aggregation result`() {
        val serviceTwo = mockk<ServiceTwo>()
        val serviceOne = ServiceOne(serviceTwo)
        
        // 直接匹配上下文接收器的调用场景
        every { 
            with(any<Raise<BusinessError>>()) {
                serviceTwo.call("1") 
            }
        } returns "1"
        
        val result = either {
            val mockResult = serviceTwo.call("1")
            assertEquals("1", mockResult)
            serviceOne.call("1")
        }
        
        when(result) {
            is Either.Left -> fail()
            is Either.Right -> assertEquals("1", result.value)
        }
    }
}

内容的提问来源于stack exchange,提问作者codependent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:42:32