Scala、Specs2和共享状态
我正在写一些规范;这看起来像:Scala、Specs2和共享状态,scala,testing,specs2,Scala,Testing,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.
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]
是共享的
- 一种解决方案是在每次测试之前使它们顺序排列并重置模拟,但这看起来很奇怪,正如文档中关于“默认并行”的内容所述:
- 另一种方法是将
移动到测试本身。但是,虽然我应该能够减少重复,但这看起来仍然像一个奇怪的结构。并且看起来val
是有状态的,而它不应该是有状态的主题
- 我还可以尝试使用不太严格的方法,通过使用
但是:验证是否存在atLestOne(依赖项)。something()
- 这并不验证该方法是否在该特定测试用例中被调用,并且
- 参数捕获和验证是痛苦的李>
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()
}
}
}
谢谢,我用一个私有方法做了一个等价的操作,该方法返回一个
元组[Subject,Dependency]
,但这更简洁。我还提到了isolated
关键字,您是否有反对或赞成该关键字的论点?我会避免使用isolated
,因为我对它在可变规格下的实现不是很有信心。它需要做各种各样的扭曲才能到达那里。还要注意的是,Scope
依赖于DelayedInit
功能,该功能不保证保留在Scala 3中。因此,如果您想安全起见:val-dependency=mock[dependency];val subject=新组件(..)
在每个示例中。。。