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

Kotlin中使用Mockito测试Micronaut RxHttpClient空指针如何解决

问题根因

该空指针异常由Mockito规则未命中、返回默认值null导致,具体触发场景包括以下几种:

  • Micronaut的RxHttpClient是final类,未引入mockito-inline依赖时,Mockito无法正常mock final类,所有方法调用默认返回null
  • mock时使用具体的HttpRequest.GET实例做参数匹配,实际代码中创建的HttpRequest是新实例,默认equals匹配未命中
  • mock的retrieve方法重载和业务代码实际调用的重载不匹配,规则未触发
  • 实例化Exchange类时未正确注入mock的RxHttpClient实例,httpClient字段本身为null
修复方案

1. 基础依赖配置

引入mockito-inline支持final类mock,推荐搭配mockito-kotlin简化Kotlin场景下的API调用:

// Gradle 依赖配置示例
testImplementation("org.mockito:mockito-inline:5.6.0")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")

2. 调整Mock规则匹配逻辑

使用Mockito参数匹配器替代具体实例匹配,确保规则命中:

  • 通用匹配用any()匹配任意HttpRequest实例
  • 需要精准校验路径时用argThat()做自定义路径匹配

3. 完整测试示例

import io.micronaut.http.HttpRequest
import io.reactivex.Flowable
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
import org.mockito.kotlin.*

class ExchangeTest {
    // 初始化mock的RxHttpClient
    private val mockHttpClient: RxHttpClient = mock()
    // 构造业务类,传入mock的httpClient
    private val exchange = Exchange(mockHttpClient)

    @Test
    fun `getSymbols returns correct symbol list`() = runTest {
        // 构造预设返回数据
        val testSymbols = listOf(Symbol("BTCUSDT"), Symbol("ETHUSDT"))
        val testExchangeInfo = ExchangeInfo(testSymbols)

        // 配置mock规则
        whenever(mockHttpClient.retrieve(
            // 精准匹配GET请求且路径以/symbols结尾
            argThat<HttpRequest<*>> { 
                it.method.name == "GET" && it.path.endsWith("/symbols") 
            },
            eq(ExchangeInfo::class.java)
        )).thenReturn(Flowable.just(testExchangeInfo))

        // 执行测试&断言
        val result = exchange.getSymbols()
        assert(result == testSymbols)
    }
}
额外注意事项
  • 建议Exchange类使用构造注入注入RxHttpClient,避免字段注入需要反射赋值的问题
  • 如果使用JUnit5注解驱动Mock,测试类需要添加@ExtendWith(MockitoExtension::class)注解
  • 校验业务代码中调用retrieve的参数顺序、重载类型和mock的方法完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:57:03