Using specs2 2.3.12
, Scala 2.11.6
. I'm seeing a type mismatch error on an example I feel I otherwise followed from the documentation. Code below:
val newUsers: Seq[(String, User)] = response.newUsers.toSeq
newUsers must contain((email: String, user: User) => (user.email.toString must be_==(email))).forall
I'm getting the following error:
[error] <redacted>/UserSpec.scala:561: type mismatch;
[error] found : org.specs2.matcher.ContainWithResult[(String, com.nitro.models.User) => org.specs2.matcher.MatchResult[String]]
[error] required: org.specs2.matcher.Matcher[Seq[(String, com.nitro.models.User)]]
[error] newUsers must contain((email: String, user: User) => (user.email.toString must be_==(email))).forall
[error] ^
[error] one error found
[error] (api/test:compileIncremental) Compilation failed
[error] Total time: 2 s, completed Aug 3, 2015 10:07:04 AM
These are the examples I was following:
// contain matcher accepting a function
Seq(1, 2, 3) must contain((i: Int) => i must be_>=(2))
Seq(1, 2, 3) must contain(be_>(0)).forall // this will stop after the first failure
I can definitely rewrite the test to get around this error, but I wanted to understand where I went wrong. Thanks for any pointers!
There's a couple of things happening here. The most important one is that your function is returning a MatchResult[String]
, when you're testing against a tuple, which the compiler isn't helping you realise because there would be an implicit type conversion if you returned a MatchResult[(String, User)]
.
You could construct your own MatchResult
, but (in my opinion) you're really going to be better off creating a Matcher[(String,User)]
, which is really simple.
If you add this to your spec:
def matchingEmail: Matcher[(String, User)] =
(pair: (String, User)) => (pair._1 == pair._2.email, s"email ${pair._1} did not match user ${pair._2}")
you can simply call it with newUsers must contain(matchingEmail).forall