如何测试Scala类私有方法?反射调用报NoSuchMethodException如何解决
报错原因
- 你实例化
GrpcAuthClientInterceptor时创建了匿名子类,调用getClass返回的是匿名子类GrpcAuthClientInterceptorTest$$anon$1的Class对象。而getToken是父类GrpcAuthClientInterceptor的私有方法,私有方法不会被子类继承,因此在子类的方法列表中无法找到该方法,抛出NoSuchMethodException。 - 你尝试的Scala原生私有方法调用写法存在参数缺失问题:
getToken需要传入4个入参,你调用invokePrivate theFunction()时没有传入任何实参,即便找到方法也会执行失败。
修复方案
你可以选择以下任意一种方式完成私有方法的测试:
方式1:调整Java反射调用逻辑
直接通过父类Class查找私有方法,同时设置方法可访问:
test("test") { // 改为使用父类GrpcAuthClientInterceptor的Class查找方法 val getToken = classOf[GrpcAuthClientInterceptor].getDeclaredMethod( "getToken", classOf[ClientAuthentication], classOf[String], classOf[String], classOf[String] ) // 私有方法需要设置可访问权限 getToken.setAccessible(true) val clientSecretBasic = new ClientSecretBasic(new ClientID(clientId), new Secret(clientSecret)) val token = getToken.invoke(grpcAuthClientInterceptor, clientSecretBasic, format, provider, null) assertTrue(token.isInstanceOf[TokenCommandResult.Success]) }
方式2:调整Scala原生私有方法调用逻辑
补全调用时的入参即可,注意需要先引入ScalaTest的私有方法测试工具类:
// 首先导入私有方法测试依赖 import org.scalatest.PrivateMethodTester._ test("test") { val theFunction = PrivateMethod[TokenCommandResult]('getToken) val clientSecretBasic = new ClientSecretBasic(new ClientID(clientId), new Secret(clientSecret)) // 按方法定义顺序传入4个入参 val result = grpcAuthClientInterceptor invokePrivate theFunction(clientSecretBasic, format, provider, null) assertTrue(result.isInstanceOf[TokenCommandResult.Success]) }
额外注意:你的测试代码中存在两个需要提前修复的语法/逻辑问题:
private var clientSecret = "缺少字符串闭合引号,会导致编译失败- 匿名子类中
override var audience: Nothing = _声明为Nothing类型,后续方法执行时转String会抛出类型转换/空指针异常,建议修改为override val audience: String = "合法的audience值"
内容的提问来源于stack exchange,提问作者user15826601
相关产品推荐
相关产品推荐

