如何创建不调用底层对象的构造函数的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存根?的主要内容,如果未能解决你的问题,请参考以下文章

C++对象模型

dotnet C# 只创建对象不调用构造函数方法

调用构造函数而不创建对象

在c++中如何调用数组对象的构造函数

在不调用构造函数的情况下创建 Vector 元素

在java语言里如何在子类中调用父类的有参构造函数