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

为何Result对象会被额外包裹在另一个Result中?

为何Result对象会被额外包裹在另一个Result中?

这个问题的核心在于Kotlin的Result是inline值类,结合JUnit 5参数化测试的参数解析逻辑,触发了额外的装箱/拆箱操作,最终导致嵌套的Result<Result<Boolean>>。

具体原因

Kotlin的Result作为inline类,在JVM层面会被编译为底层基础类型(比如这里的Boolean),但保留了类型元信息。当你通过Arguments.of(Result.success(true))传递参数时:

  1. JUnit的参数解析器会把Result实例解包成它的底层值true
  2. 因为测试方法参数声明为Result类型,JUnit又会自动把true重新包装成一个新的Result<Boolean>
  3. 最终就出现了外层Result包裹原本Result<Boolean>的嵌套情况

修复方案

方案1:用普通类包裹Result

创建一个简单的数据类封装Result,让JUnit直接处理普通类而非inline类:

import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream

// 用数据类封装Result,避免JUnit直接处理inline类
data class ResultHolder<T>(val value: Result<T>)

class TestTest {
    companion object {
        @JvmStatic
        fun streamOfArguments(): Stream<Arguments> {
            return Stream.of(
                Arguments.of(ResultHolder(Result.success(true)))
            )
        }
    }

    @ParameterizedTest
    @MethodSource("streamOfArguments")
    fun testArgumentParameter(holder: ResultHolder<Boolean>) {
        val actualResult = holder.value
        println(actualResult::class) // 输出class kotlin.Result
        actualResult.onSuccess {
            println(it) // 输出true
        }
    }
}

方案2:将Result包装进数组传递

Arguments.of()接收可变参数,单个inline类会被特殊处理,但传入数组时,JUnit会直接保留数组内的原类型:

import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream

class TestTest {
    companion object {
        @JvmStatic
        fun streamOfArguments(): Stream<Arguments> {
            return Stream.of(
                // 把Result包装进数组,跳过JUnit的inline类解包逻辑
                Arguments.of(arrayOf(Result.success(true)))
            )
        }
    }

    @ParameterizedTest
    @MethodSource("streamOfArguments")
    fun testArgumentParameter(actualResult: Result<Boolean>) {
        println(actualResult::class) // 输出class kotlin.Result
        actualResult.onSuccess {
            println(it) // 输出true
        }
    }
}

两种方案都能让你拿到原本的Result<Boolean>实例,彻底避免嵌套问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:55:12