Specs2 Result.foreach 可以像匹配器一样工作吗?
Can Specs2 Result.foreach be made to work like a matcher?
使用 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,但没有提到我能找到的这种行为。
解决方法:将 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, the goal of "unit specifications" is to let users have multiple expectations per example without the need to use and
. In light of this, the behavior of Result.foreach
indeed seems misleading. If you think this is a bug, you may consider opening an issue。
这可能应该得到更好的记录。 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
}
}
}
returns
[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
使用 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,但没有提到我能找到的这种行为。
解决方法:将 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, the goal of "unit specifications" is to let users have multiple expectations per example without the need to use and
. In light of this, the behavior of Result.foreach
indeed seems misleading. If you think this is a bug, you may consider opening an issue。
这可能应该得到更好的记录。 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
}
}
}
returns
[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