如何创建不调用底层对象的构造函数的ScalaMock存根?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何创建不调用底层对象的构造函数的ScalaMock存根?相关的知识,希望对你有一定的参考价值。
考虑以下示例Scala类和单元测试:
class BrokenClass(s: String) {
private val len = s.length
def length(): Int = len
}
class BrokenTest extends FlatSpec with Matchers with MockFactory {
"A BrokenClass" should "stub correctly" in {
val stubThing = stub[BrokenClass]
(stubThing.length _) when () returns (10)
stubThing.length should equal (10)
}
}
在旧版本的ScalaMock中,此代码可以正常工作。使用Scala 2.12和ScalaMock 3.6,我得到一个NullPointerException,因为即使我正在创建一个存根,它仍然会调用BrokenClass构造函数的“s.length”行。所以它试图取消引用“s”,它是null,因为我没有传递任何东西,因为我想要的是一个存根,在调用特定方法时返回一个特定的值。
有没有办法创建存根而不试图调用对象的构造函数?为什么这适用于旧版本?
答案
ScalaMock使用宏定义生成子类。在编译器运行期间扩展/评估该宏。
由于mocks是子类,因此将调用超类的构造函数 - 没有例外。你可以使用一些cglib法术来解决这个问题,但这不是我熟悉的事情。
因此,在旧的ScalaMock版本中可能已经可以实现这一功能,但是此功能不会在当前实现的情况下很快恢复。
另一个选择是实际上自己子类化这个东西并模拟子类
class NotSoBrokenClass extends BrokenClass("")
...
val nsb = mock[NotSoBrokenClass]
...
这在某些情况下有效,但如果构造函数依赖于非最终方法调用,您也会看到有趣的行为(例如NPE)。
以上是关于如何创建不调用底层对象的构造函数的ScalaMock存根?的主要内容,如果未能解决你的问题,请参考以下文章