Scala、Specs2 和共享状态

Scala, Specs2 and shared state

我正在编写一些 Specs2 规范;看起来像:

class ComponentSpecification extends Specification with Mockito {

  private val dependency = mock[Dependency]
  private val subject = new Component(..)

  "methodOne" should {
    "handle happy path" in {
       val result = subject.methodOne("Param1", 42)
       result must ...
       there was one(dependency).something()
    }

    "deal with border case" in {
       val result = subject.methodOne("", -1)
       result must ...
       there was one(dependency).something()
    }
  }
}

但是,这些测试失败了,因为 mock[Dependency] 是共享的。

it encourages to write independent examples when the result of a given example should not be influenced by others

所以我的问题是:

如何在 mock 上创建具有详细验证的可读测试。

非常感谢。

Scopes 可以像这样为每个测试提供新鲜状态

class ComponentSpecification extends mutable.Specification with Mockito {
  trait FooScope extends Scope {
    val dependency = mock[Dependency]
    val subject = new Component(dependency)
  }

  "methodOne" should {
    "handle happy path" in new FooScope {
      val result = subject.methodOne("Param1", 42)
      there was one(dependency).something()
    }

    "deal with border case" in new FooScope {
      val result = subject.methodOne("", -1)
      there was one(dependency).something()
    }
  }
}

无需在每次测试前重置模拟。

我打算接受@Mario Galic 的回答。然而,关于@Eric(Specs2 的作者)的评论,我以一种按预期创建上下文但删除重复的方法结束。通过使用模式匹配,我提取了有趣的部分:

class ComponentSpecification extends mutable.Specification with Mockito {
  def givenOneCallToMethodOneWithDependency(s:String, i:Int):(Result, Dependency) = {
    val dependency = mock[Dependency]
    val subject = new Component(dependency)
    val result = subject.methodOne(s, i)
    (result, dependency)
  }

  "methodOne" should {
    "handle happy path" in new FooScope {
      val (result, dependency) = givenOneCallToMethodOneWithDependency("Param1", 42)
      there was one(dependency).something()
    }

    "deal with border case" in new FooScope {
      val (result, dependency) = givenOneCallToMethodOneWithDependency("", -1)

      there was one(dependency).something()
    }
  }
}