如何在Scala中模拟由对象中的函数初始化的val?

如何在Scala中模拟由对象中的函数初始化的val?,scala,mocking,mockito,Scala,Mocking,Mockito,我在Scala中有一个对象,如下所示 object Foo { val launchDate = LocalDate.now() ... } 我需要做一个单元测试,在这个测试中,我将lauchDate替换为给定的日期,例如:2001年6月25日。有没有办法模拟启动日期?你会推荐我使用哪种框架 谢谢你org.mockito.internal.util.reflection.Whitebox似乎工作得很好。既然你用mockito标记了这个问题,我想你已经在你的类路径上了 Whitebox

我在Scala中有一个对象,如下所示

object Foo {

  val launchDate = LocalDate.now()
  ...
}
我需要做一个单元测试,在这个测试中,我将lauchDate替换为给定的日期,例如:2001年6月25日。有没有办法模拟
启动日期
?你会推荐我使用哪种框架


谢谢你

org.mockito.internal.util.reflection.Whitebox似乎工作得很好。既然你用mockito标记了这个问题,我想你已经在你的类路径上了

Whitebox.setInternalState(Foo, launchDate, <your date>)
Whitebox.setInternalState(Foo,launchDate,)

org.mockito.internal.util.reflection.Whitebox似乎工作正常。既然你用mockito标记了这个问题,我想你已经在你的类路径上了

Whitebox.setInternalState(Foo, launchDate, <your date>)
Whitebox.setInternalState(Foo,launchDate,)

我听说ScalaMock支持使用方法
mockObject
模拟单例对象的功能。但它来自ScalaMock 3

但是,如果您有一个trait而不是object,那么您可以将ScalaMock 4与ScalaTest一起使用,即使用
proxy.MockFactory

import java.time.LocalDate

import org.scalamock.scalatest.proxy.MockFactory
import org.scalatest.FunSuite

class FooTest extends FunSuite with MockFactory {
  test("it should return local date") {
    val launchDate: LocalDate = LocalDate.of(2017, 6, 15)
    val m = mock[FooService]
    m.expects('launchDate)().returning(launchDate)
    assertResult(launchDate)(m.launchDate)
  }
}
build.sbt
依赖项:

libraryDependencies ++= Seq("org.scalactic" %% "scalactic" % "3.0.5",
                            "org.scalatest" %% "scalatest" % "3.0.5" % Test,
                            "org.scalamock" %% "scalamock" % "4.1.0" % Test)

我听说ScalaMock支持使用方法
mockObject
模拟单例对象的特性。但它来自ScalaMock 3

但是,如果您有一个trait而不是object,那么您可以将ScalaMock 4与ScalaTest一起使用,即使用
proxy.MockFactory

import java.time.LocalDate

import org.scalamock.scalatest.proxy.MockFactory
import org.scalatest.FunSuite

class FooTest extends FunSuite with MockFactory {
  test("it should return local date") {
    val launchDate: LocalDate = LocalDate.of(2017, 6, 15)
    val m = mock[FooService]
    m.expects('launchDate)().returning(launchDate)
    assertResult(launchDate)(m.launchDate)
  }
}
build.sbt
依赖项:

libraryDependencies ++= Seq("org.scalactic" %% "scalactic" % "3.0.5",
                            "org.scalatest" %% "scalatest" % "3.0.5" % Test,
                            "org.scalamock" %% "scalamock" % "4.1.0" % Test)

在这里,我将稍微切题,并说日期/时间/时钟是“依赖注入”的典型例子之一。我使用引号,因为我认为只将其作为构造函数arg传递比所有那些花哨的框架都好

我倾向于认为这种嘲弄应该是最后的手段。我宁愿:

class Foo(clock: { def now(): LocalDate }) {
  val launchDate = clock.now()
  // ... rest of Foo's original implementation ...
}

object FooRealtime extends Foo(LocalDate) {
} // previous users of Foo can just use FooRealtime

然后,在测试中,您可以传入一个不同的实现,它返回您想要的任何日期。

我将在这里稍微切题,并说日期/时间/时钟是您应该使用“依赖项注入”进行操作的典型示例之一。我使用引号,因为我认为只将其作为构造函数arg传递比所有那些花哨的框架都好

我倾向于认为这种嘲弄应该是最后的手段。我宁愿:

class Foo(clock: { def now(): LocalDate }) {
  val launchDate = clock.now()
  // ... rest of Foo's original implementation ...
}

object FooRealtime extends Foo(LocalDate) {
} // previous users of Foo can just use FooRealtime

然后在测试中,您可以传入一个不同的实现,该实现返回您想要的任何日期。

如果使用mockito,您是否尝试过Whitebox?如果使用mockito,您是否尝试过Whitebox?