代码之家  ›  专栏  ›  技术社区  ›  Huitzilopochtli

如何创建不调用底层对象构造函数的scalamock存根?

  •  1
  • Huitzilopochtli  · 技术社区  · 7 年前

    考虑下面的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”的引用,这是空的,因为我没有传递任何东西给它,因为我只需要一个存根,在调用特定方法时返回特定值。

    有没有一种方法可以创建存根而不调用对象的构造函数?为什么这在旧版本中有效?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Philipp    7 年前

    scalamock使用宏定义生成子类。 该宏在编译器运行期间得到扩展/求值。

    由于mock是子类,因此将调用超类的构造函数-没有异常。 你也许可以使用一些cglib魔法来解决这个问题,但这不是我所熟悉的。

    因此,这在旧的scalamock版本中是可能的,但是这个特性在当前实现中不会很快恢复。

    另一种选择是自己将这个东西划分为子类并模拟子类

    class NotSoBrokenClass extends BrokenClass("")
    ...
    val nsb = mock[NotSoBrokenClass]
    ...
    

    这在某些情况下是有效的,但是如果构造函数依赖于非最终方法调用,那么您也会看到有趣的行为(例如npe)。

    推荐文章