【问题标题】:Mocking Scala Objects and Functions模拟 Scala 对象和函数
【发布时间】:2017-09-14 12:18:54
【问题描述】:

我有一个 Scala 对象,它包含一些实用函数。这些函数由同一对象中存在的其他函数或其他类/对象调用。是否可以模拟这个对象或函数,以便我可以对调用它们的类进行单元测试。

例子:

object Util {

  def methodA() = { 
    //other code
    methodB() 
    //other code
  }

  def methodB() = { 
    //other code
    methodC() 
    //other code
  }

  def methodC() = { ... }

}

这里我从另一个类调用对象函数

class Data {

  //other code

  def call() = {
    //other code
    Util.methodA()
    //other code
  }
}

如何对 Data 类的函数 call() 进行单元测试?在 Java 中,我可以为 Util 创建一个模拟对象并设置对 methodA() 调用的期望,但这在 Scala 中是不可能的,因为没有模拟库支持模拟 Scala 对象。

【问题讨论】:

  • 有很多 scala 模拟选项。例如,请参阅scalatest.org/user_guide/testing_with_mock_objects。任何快速搜索都会为您带来很多选择
  • 是的,我已经看到了您提供的链接,但其中提到的模拟框架都不支持模拟 Scala 对象。 ScalaMock 2 支持模拟对象,但在 ScalaMock 3 中已停止使用,这是 Scala 2.11 编译器的最新版本。

标签: scala unit-testing mocking


【解决方案1】:

从某种意义上说,问题在于您使用的模式类似于 Java 中的静态类。您不能模拟静态类,这就是 Java 模式通常不支持这种方法的原因。

另一方面,在 Scala 中你可以。让 Util 扩展一个特征并实现它。

trait UtilityMethods {
 def methodA()
 def methodB()
}

object Utils extends UtilityMethods {
  def methodA() = {}
  def methodB() = {}
}

然后在你的测试中:

val mockedUtils = mock[UtilityMethods]

(使用模拟)。显然,您必须在代码中传递 UtilityMethods 而不是 Utils,就像在 Java 中使用接口一样。

一般来说,您也可以使用隐式作用域来注入函数,从而在没有类似静态对象的方法的情况下模拟这些依赖项,但上面的方法非常接近 Java 模式,应该感觉很舒服。

【讨论】:

  • 你能举例说明如何使用隐式作用域吗?
  • 当然。有几种方法可以解决它。在寻找 DI 方法时,我经常使用隐式,因为它们是相似的模式 - 由外部参与者注入的提供的依赖项。在这种情况下,想想class Data(implicit utils: UtilityMethods),然后剩下的就是 - 在需要的地方提供 UtilityMethods 的实现。您也可以使用implicit classes 将这些方法放在Data 本身上。每个都是避免“静态”模式的方法,同时也避免了这些依赖关系。
猜你喜欢
  • 2011-04-04
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多