Kotlin中如何测试带自定义对象列表参数的私有方法?
Kotlin中如何测试带自定义对象列表参数的私有方法?
这个问题我之前也踩过坑,主要是两个关键点没处理对:伴生对象的反射定位和泛型类型擦除的影响,咱们一步步来解决:
先分析你遇到的错误原因
- 第一个
NoSuchMethodException:从错误信息里的ClassToBeTested$Companion.delete能看出来,你的delete方法是定义在伴生对象里的,但你用ClassToBeTested.javaClass去获取方法,这是在主类里找,自然找不到属于伴生对象的方法。 - 第二个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是类的实例私有方法,那步骤稍微调整:
- 获取主类的Class:
val clazz = ClassToBeTested::class.java - 获取方法时用主类的Class,调用
invoke时传入类的实例对象:
val instance = ClassToBeTested() // 假设是无参构造 val method = clazz.getDeclaredMethod(...) val testId = method.invoke(instance, ...) as Long?
备注:内容来源于stack exchange,提问作者noddy
相关产品推荐
相关产品推荐

