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

Kotlin中如何测试带自定义对象列表参数的私有方法?

Kotlin中如何测试带自定义对象列表参数的私有方法?

这个问题我之前也踩过坑,主要是两个关键点没处理对:伴生对象的反射定位和泛型类型擦除的影响,咱们一步步来解决:

先分析你遇到的错误原因

  1. 第一个NoSuchMethodException:从错误信息里的ClassToBeTested$Companion.delete能看出来,你的delete方法是定义在伴生对象里的,但你用ClassToBeTested.javaClass去获取方法,这是在主类里找,自然找不到属于伴生对象的方法。
  2. 第二个Kotlin编译错误:List<CustomObject>::class.java是非法写法,因为JVM的泛型是类型擦除的,运行时根本不存在List<CustomObject>这个类型,只有List,所以Kotlin不允许在类字面量里带泛型参数。

正确的反射测试步骤

步骤1:定位伴生对象的Class

因为你的方法在伴生对象里,首先要拿到伴生对象的Class实例,有两种方式:

  • 方式一:直接通过伴生对象实例获取
val companionClass = ClassToBeTested.Companion.javaClass
  • 方式二:从主类的内部类中查找(适合不知道伴生对象名称的情况)
val companionClass = ClassToBeTested::class.java.getDeclaredClasses()
    .first { it.simpleName == "Companion" }

步骤2:获取私有方法并设置可访问

因为泛型擦除,方法的参数类型在运行时就是List,所以直接用List::class.java即可,不用管泛型参数:

val method = companionClass.getDeclaredMethod(
    "delete",
    String::class.java,
    List::class.java,
    String::class.java,
    String::class.java,
    String::class.java
)
// 开启私有方法的访问权限
method.isAccessible = true

步骤3:调用方法

调用时第一个参数要传入伴生对象的实例(也就是ClassToBeTested.Companion),然后依次传参数:

val testId = method.invoke(
    ClassToBeTested.Companion,
    someId1,
    aList,
    someId2,
    someId3,
    someId4
) as Long?

补充:如果是实例方法(非伴生对象)的情况

如果你的delete是类的实例私有方法,那步骤稍微调整:

  1. 获取主类的Class:val clazz = ClassToBeTested::class.java
  2. 获取方法时用主类的Class,调用invoke时传入类的实例对象:
val instance = ClassToBeTested() // 假设是无参构造
val method = clazz.getDeclaredMethod(...)
val testId = method.invoke(instance, ...) as Long?

备注:内容来源于stack exchange,提问作者noddy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 15:42:42