问题描述
使用 Specs2,如果我这样做:
1 must beEqualTo(2)
1 must beEqualTo(1)
测试失败(如预期)
如果我这样做:
Result.foreach(1 to 10) { i =>
i must_== 2
}
Result.foreach(1 to 10) { i =>
i must_== i
}
测试通过
对于 Result.foreach
,我必须使用 and
使测试失败(如预期):
Result.foreach(1 to 10) { i =>
i must_== 2
} and
Result.foreach(1 to 10) { i =>
i must_== i
}
这是为什么?
有没有办法让它以一种不那么令人惊讶的方式工作?这很容易出错 - 很容易没有注意到有人没有输入 and
我检查了 Specs2 user guide,但没有提到我可以找到的这种行为。
解决方法
这可能应该更好地记录。 Result.foreach
函数确实应该是无副作用的。如果你想要副作用,你可以直接在你的规范中调用 foreach
因为这个与可变规范的“抛出”行为相关联:
class TestMutableSpec extends mutable.Specification {
"foreach must fail" >> {
foreach(1 to 10) { i =>
i must_== 2
}
foreach(1 to 10) { i =>
i must_== i
}
}
}
返回
[info] TestMutableSpec
[error] x foreach must fail
[error] There are 9 failures
[error] 1 != 2
[error] 3 != 2
[error] 4 != 2
[error] 5 != 2
[error] 6 != 2
[error] 7 != 2
[error] 8 != 2
[error] 9 != 2
[error] 10 != 2 (TestSpec.scala:19)
[info] Total for specification TestMutableSpec
[info] Finished in 121 ms
[info] 1 example,1 failure,0 error
,
解决方法:将 AllExpectations 混合到您的 Specification
中:
class QuickStartSpec extends mutable.Specification with AllExpectations {
"foreach must fail" >> {
Result.foreach(1 to 10) { i =>
i must_== 2
}
Result.foreach(1 to 10) { i =>
i must_== i
}
}
}
这会产生:
sbt> testOnly QuickStartSpec
[info] QuickStartSpec
[error] x foreach must fail
[error] 1 != 2 (QuickStartSpec.scala:8)
注意:我知道这不是 AllExpectations
特性的主要目的。然而,这似乎是一个明智的解决方案,因为 Result.foreach
的行为方式与可变规范中的匹配器不同。
此外,according to the docs,“单位规范”的目标是让用户对每个示例有多种期望,而无需使用 and
。有鉴于此,Result.foreach
的行为确实似乎具有误导性。如果您认为这是一个错误,您可以考虑 opening an issue。