Specs2:集合匹配器上的类型不匹配编译错误

Specs2: type mismatch compilation error on collection matchers

使用 specs2 2.3.12、Scala 2.11.6。我在一个示例中看到类型不匹配错误,我觉得我从文档中得到了其他信息。代码如下:

val newUsers: Seq[(String, User)] = response.newUsers.toSeq
newUsers must contain((email: String, user: User) => (user.email.toString must be_==(email))).forall

我收到以下错误:

[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

这些是我关注的examples

// 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

我绝对可以重写测试来绕过这个错误,但我想了解我哪里出错了。感谢指点!

这里发生了几件事。最重要的是,当您针对元组进行测试时,您的函数返回了一个 MatchResult[String],而编译器并没有帮助您意识到这一点,因为如果您返回一个 [=12],将会进行隐式类型转换=].

您可以构建自己的 MatchResult,但(在我看来)您最好创建一个 Matcher[(String,User)],这非常简单。

如果将此添加到您的规范中:

  def matchingEmail: Matcher[(String, User)] =
    (pair: (String, User)) => (pair._1  == pair._2.email, s"email ${pair._1} did not match user ${pair._2}")

你可以简单地用 newUsers must contain(matchingEmail).forall

来调用它