1

我正在尝试使用 scalatest v.2.0.M5b 为 NodeSeq 编写一个简单的自定义匹配器。

package test

import org.scalatest.matchers.{MatchResult, Matcher, ShouldMatchers}

import scala.xml.NodeSeq
import org.scalatest.FunSpec

class MySpec extends FunSpec with ShouldMatchers with MyMatcher {

  describe("where is wrong?") {
    it("showOK") {
      val xml = <span>abc</span>
      xml should contn("b")
    }
  }
}

trait MyMatcher {

  class XmlMatcher(str: String) extends Matcher[NodeSeq] {
    def apply(xml: NodeSeq) = {
      val x = xml.toString.contains(str)
      MatchResult(
        x,
        "aaa",
        "bbb"
      )
    }
  }

  def contn(str: String) = new XmlMatcher(str)

}

当我编译它时,它会报告错误:

[error] /Users/freewind/src/test/scala/test/MyMacher.scala:14: overloaded method value should with alternatives:
[error]   (beWord: MySpec.this.BeWord)MySpec.this.ResultOfBeWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and>
[error]   (notWord: MySpec.this.NotWord)MySpec.this.ResultOfNotWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and>
[error]   (haveWord: MySpec.this.HaveWord)MySpec.this.ResultOfHaveWordForSeq[scala.xml.Node] <and>
[error]   (rightMatcher: org.scalatest.matchers.Matcher[scala.collection.GenSeq[scala.xml.Node]])Unit
[error]  cannot be applied to (MySpec.this.XmlMatcher)
[error]       xml should contn("b")
[error]           ^
[error] one error found
[error] (test:compile) Compilation failed

哪里错了?


更新:

我使用的 build.sbt 文件:

name := "scalatest-test"

scalaVersion := "2.10.1"

version := "1.0"

resolvers ++= Seq("snapshots"     at "http://oss.sonatype.org/content/repositories/snapshots",
            "releases"        at "http://oss.sonatype.org/content/repositories/releases",
            "googlecode"      at "http://sass-java.googlecode.com/svn/repo"
            )

libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M5b" % "test"

还有一个演示项目:https ://github.com/freewind/scalatest-test

4

1 回答 1

1

对于 scala 编译器抱怨的原因,请参见这个答案

但似乎 ScalaTest API 从那时起发生了很大变化,因此提出的两种解决方案都需要进行一些修改(针对 ScalaTest 2.0.M5b 进行了测试):

  • 将 NodeSeq 的所有实例替换为 GenSeq[Node],以便类型在任何地方都匹配。

    参见SeqShouldWrapperScalaTest 类。

  • 或者,使用转换函数显式地包装 xml,即手动设置所需的类型,但我不推荐这样做,因为它会使客户端代码变得丑陋。

    new AnyRefShouldWrapper(xml).should(contn("b"))

顺便说一句,在 github 上有一个小而完整的项目供其他人调整是件好事。它使这个问题更具吸引力。

于 2013-06-14T14:17:17.893 回答