2

我想在 Scala 中设置一个测试,创建一个模拟配置来提供某些值。我正在使用 ScalaTest 3.0.1、ScalaMock 3.4.2 和 typesafe 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()没有使用一样。应该如何编码,以便可以模拟一次并重复调用该方法?为什么第二次尝试失败?有没有办法重置模拟以便可以重用?

4

2 回答 2

3

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

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)
  }

}
于 2017-01-27T09:11:37.070 回答
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)
  }

}

这很容易,因为您的测试根本不会改变。您只是将逻辑从“全局本地”变量移动到单个测试的本地范围内。

于 2017-01-26T21:42:53.610 回答