如何为重复的方法调用设置一次ScalaMock?

时间:2017-01-26 20:51:04

标签: scala scalatest scalamock

我想在Scala中设置一个测试,创建一个模拟配置来提供某些值。我使用的是ScalaTest 3.0.1,ScalaMock 3.4.2, 和类型安全1.3.1。目标是在运行测试之前模拟配置的值。文档在 http://www.scalatest.org/user_guide/testing_with_mock_objectshttp://scalamock.org/user-guide/features/似乎提供了 几个选项。首先,这里有一些目标代码:

import com.typesafe.config.Config
class Sample(config: Config) {
    private val aValue = config.getDouble("aValue")
}

似乎应该可以将所有内容设置为一次,或者在每次测试之前设置所有内容。这种尝试失败了:

class SampleSpec extends FlatSpec with MockFactory with BeforeAndAfterAll {

  private val mockConfig = mock[Config]

  override def beforeAll {
    (mockConfig.getDouble _).expects("aValue").returning(1.0).anyNumberOfTimes()
  }

  "testOne" should "return 1" in {
    new Sample(mockConfig)
  }

  "testTwo" should "return 1" in {
    new Sample(mockConfig)
  }

}

第一次测试成功,但夹具中的第二次测试失败,产生了这个错误:

Unexpected call: <mock-1> Config.getDouble(aValue)

Expected:
inAnyOrder {

}

Actual:
  <mock-1> Config.getDouble(aValue)
ScalaTestFailureLocation: scala.Option at (Option.scala:120)
org.scalatest.exceptions.TestFailedException: Unexpected call: <mock-1> Config.getDouble(aValue)

Expected:
inAnyOrder {

}

这是另一种方法:

class SampleSpec extends FlatSpec with MockFactory with BeforeAndAfter {

  private val mockConfig = mock[Config]

  before {
    (mockConfig.getDouble _).expects("aValue").returning(1.0)
  }

  "testOne" should "return 1" in {
    new Sample(mockConfig)
  }

  "testTwo" should "return 1" in {
    new Sample(mockConfig)
  }

}

它产生了这个例外:

An exception or error caused a run to abort: assertion failed: Null expectation context - missing withExpectations?
java.lang.AssertionError: assertion failed: Null expectation context - missing withExpectations?

为什么第一次尝试失败?该测试指定getDouble可以被调用任意次,而第二次 测试失败,好像anyNumberOfTimes()未被使用。应如何对其进行编码,以便可以模拟该方法一次 反复调用?为什么第二次尝试失败?有没有一种方法可以重置模拟,以便可以重复使用?

2 个答案:

答案 0 :(得分:1)

每次重新创建模拟,手动是我可以让它工作的唯一方法:

class SampleSpec extends FlatSpec with MockFactory {

  private def mockConfig = {
    val mocked = mock[Config]
    (mocked.getDouble _).expects("aValue").returning(1.0).anyNumberOfTimes()
    mocked
  }

  "testOne" should "return 1" in {
    new Sample(mockConfig)
  }

  "testTwo" should "return 1" in {
    new Sample(mockConfig)
  }

}

这很容易,因为您的测试根本没有变化。您只需从全局本地&#34;移动逻辑。变量并进入个别测试的局部范围。

答案 1 :(得分:1)

我还想指出这个文档页面,风格略有不同(使用特征):

http://scalamock.org/user-guide/sharing-scalatest/#fixture-contexts

例如:

class SampleSpec extends FlatSpec with OneInstancePerTest with MockFactory {

  private val mockConfig = mock[Config]

  (mockConfig.getDouble _).expects("aValue").returning(1.0).anyNumberOfTimes

  "testOne" should "return 1" in {
    new Sample(mockConfig)
  }

  "testTwo" should "return 1" in {
    new Sample(mockConfig)
  }

}