我有一个示例对象:
object Foo {
private def sayFoo = "Foo!"
}
我想在没有以下解决方法的情况下测试私有的sayFoo方法: 1.没有将其定义为包私有 2.没有将其定义为受保护,而是在测试类中继承它
我看到了一个可能的解决方案,即扩展privateMethodTester,但它没有 似乎只为类对象工作。
现在,我知道有些人,如果不是很多人,说你不是要测试私人方法,而只是测试公共方法(api)。尽管如此,我仍然想测试它们。
高级
答案 0 :(得分:2)
无法通过任何标准手段进行测试。
但是,如果您需要“覆盖”该部分代码,请测试在其实现中使用该私有方法的方法。它是间接的,被授予,但它确实有效地测试了代码。
例如,在您的课程中,您可以使用另一种方法:
def dontSayBar = {
sayFoo()
println("Other processing...")
}
如果进行测试,这将“覆盖”私有方法中的代码。
P.S。一个好的经验法则是,如果您看到代码未在coverage运行中显示,那么您可能实际上并不需要该代码。
答案 1 :(得分:2)
正如其他人所说,没有办法直接测试私有方法,特别是对象。 但是,您可以通过使用反射作弊来绕过限制。
我不确定使用Scala反射API是否有更简洁的方法来执行相同操作,但是以下使用Java反射的代码确实有效:
val m = Foo.getClass.getDeclaredMethod("sayFoo")
val inst = Foo.getClass.getField("MODULE$").get()
m.setAccessible(true)
m.invoke(inst)
首先,您需要获得sayFoo
方法的引用。接下来,您需要获取对Foo对象的单例实例的引用,该实例保存在MODULE$
静态字段中。
一旦你有两个引用,你只需告诉JVM从方法中删除访问限制,使其可访问。
这显然是一个丑陋的黑客,但如果谨慎使用并且仅用于测试目的可能是有用的。
答案 2 :(得分:0)
可能有人已经这样做了:注释宏@Testable
如何通过暴露私有成员的方法发出对象,但仅在编译测试时(以及其他对象)。
scala> object X { private def f = 42 ; def g = 2 * f }
defined object X
scala> X.g
res1: Int = 84
scala> object X { private def f = 42 ; def g = 2 * f ; def testable = new { def f = X.this.f } }
defined object X
scala> X.testable.f
warning: there was one feature warning; re-run with -feature for details
res2: Int = 42
scala> object X { private def f = 42 ; def g = 2 * f ; def testable = new Dynamic { def selectDynamic(name: String) = X.this.f } }
defined object X
scala> X.testable.f
warning: there was one feature warning; re-run with -feature for details
res4: Int = 42
或者,它可以发出不同的object TestableX
。