Scala测试:替换函数实现

Scala测试:替换函数实现,scala,mocking,mockito,scalatest,scalamock,Scala,Mocking,Mockito,Scalatest,Scalamock,使用ScalaTest,我想替换测试用例中的函数实现。我的用例: object Module { private def currentYear() = DateTime.now().year.get def doSomething(): Unit = { val year = currentYear() // do something with the year } } 我想编写一个单元测试testingModule.doSomething,但我不想让这个测试用

使用ScalaTest,我想替换测试用例中的函数实现。我的用例:

object Module {
  private def currentYear() = DateTime.now().year.get

  def doSomething(): Unit = {
    val year = currentYear()
    // do something with the year
  }
}
我想编写一个单元测试testing
Module.doSomething
,但我不想让这个测试用例依赖于测试运行的实际年份

在动态语言中,我经常使用一个可以替换函数实现以返回固定值的构造

我希望我的测试用例将
Module.currentYear
的实现更改为始终返回2014,无论实际年份是什么

我发现了几个模拟库(Mockito、ScalaMock等等),但它们都只能创建新的模拟对象。它们似乎都无法取代方法的实现


有办法吗?如果不是,我如何在不依赖于测试运行年份的情况下测试这样的代码呢?

一种方法就是让测试用例能够访问
在这一年做一些事情(例如,让它受包保护)。这也很好,因为它将查找依赖项和实际使用依赖项分离开来


另一种方法是将您的逻辑放在trait中,使
currentYear
方法受到保护,并让对象成为该trait的实例。这样,您就可以在测试中根据特性创建一个自定义对象,而不需要任何模拟库。

ScalaMock可以模拟单例对象,它在这里说:

除了特征(接口)和功能外,它还可以模拟:

班级

单一对象和伴生对象(静态方法)


这两种解决方案都是有效的,但我不喜欢它的设计。模块的用户不需要知道模块正在用一年的时间做一些事情。动态语言允许以这种方式删除函数。scala中没有这样做的方法吗?那就是公共接口,对象的一部分,它是在trait中实现的,是包私有的实现细节,所以用户不必知道。如果你真的想模仿动态语言,那么看看关于scalamock的一些最佳答案。