Reputation: 8653
Using Specs2, if I do:
1 must beEqualTo(2)
1 must beEqualTo(1)
The test fails (as expected)
If I do:
Result.foreach(1 to 10) { i =>
i must_== 2
}
Result.foreach(1 to 10) { i =>
i must_== i
}
The test passes
For Result.foreach
I have to use and
to make the test fail (as expected):
Result.foreach(1 to 10) { i =>
i must_== 2
} and
Result.foreach(1 to 10) { i =>
i must_== i
}
Why is this?
Is there a way to make it work in a less surprising way? This is very error prone - it's way too easy to not notice somebody didn't type and
I checked the Specs2 user guide but there's no mention of this behaviour that I can find.
Upvotes: 1
Views: 269
Reputation: 15557
This should probably be better documented. The Result.foreach
function is indeed supposed to be non side-effecting. If you want side-effects you can call foreach
directly in your specification because this one is wired in with the "throwing" behaviour of a mutable specification:
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
Upvotes: 2
Reputation: 421
Workaround: mix AllExpectations into your 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
}
}
}
This produces:
sbt> testOnly QuickStartSpec
[info] QuickStartSpec
[error] x foreach must fail
[error] 1 != 2 (QuickStartSpec.scala:8)
Note: I'm aware of the fact that this is not the primary purpose of the AllExpectations
trait. However, this seems a sensible solution, given that Result.foreach
behaves in a different way than a matcher inside a mutable specification.
Also, 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.
Upvotes: 1