scalac finds wrong forAll method in ScalaTest test
我有一个扩展
1 2 3 | forAll(mySequence) { myItem => myItem.applicationID should be (foo.applicationID) } |
编译失败,因为 scalac 说:
1 2 3 | [error] APISpec.scala:253: value applicationID is not a member of Seq[com.company.Item] [error] myItem.applicationID should be (foo.applicationID) [error] ^ |
事实证明,至少根据 Eclipse Scala IDE,编译器将"forAll"解析为该方法,在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** * Performs a property check by applying the specified property check function to arguments * supplied by the specified generators. * * <p> * Here's an example: * </p> * * [cc lang="scala"] * import org.scalacheck.Gen * * // Define your own string generator: * val famousLastWords = for { * s <- Gen.oneOf("the","program","compiles","therefore","it","should","work") * } yield s * * forAll (famousLastWords) { (a: String) => * a.length should equal ((a).length) * } * |
*
* @param fun 属性检查函数以应用于生成的参数
*/
def forAll[A](genA: Gen[A], configParams: PropertyCheckConfigParam*)(fun: (A) => Unit)
(隐式
配置:PropertyCheckConfig,
shrA:收缩[A]
) {
// 正文省略
}
[/cc]
这不是我想在这里使用的
这是 ScalaTest 中的错误吗(即这两个方法不应该都命名为
我应该如何调用正确的方法?
Is this a bug in ScalaTest
它演示了方法重载的限制。
在一篇关于无私特质的文章中,Bill Venners 将这种模式描述为此类命名冲突的解决方法。
在您的情况下,首选一个重载,因为它是在"派生类"中定义的。
(我认为;我不是这些测试框架的用户,并且生成了其中一个源等,因此测试这不是启动 sbt 并查看代码的简单问题。)
(编辑:scaladoc 说你应该
(编辑:解释命名位:参见规范第 2 章的开头,其中说名称绑定具有优先级,并且您继承的名称比您导入的名称具有更高的优先级。)
无论如何,一种解决方案是重新混入
另一种解决方案是通过重命名导入方法:
1 |
尝试使用"-Xprint:typer"、"-Xlog-implicit-conversions"选项来查看发生了什么很有用。在您的情况下,ScalaCheck 1.10.
中的隐式视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import org.scalatest._ import org.scalatest.prop._ //class MySpec extends FeatureSpec with Matchers with GeneratorDrivenPropertyChecks class MySpec extends FeatureSpec with Matchers with GeneratorDrivenPropertyChecks with Inspectors { case class Foo(id: Int) val items = 1 to 10 map (Foo.apply(_)) forAll(items) { x => Console println x.id } } object Test extends App { case class Foo(id: Int) val items = 1 to 10 map (Foo.apply(_)) val sut = new MySpec sut.forAll(items) { x => Console println x.id } //sut.forAll[Foo](items) { x => Console println x.i } } |
一些调试输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* [info] /home/apm/projects/skala-unit-tests/src/test/scala/maqi/MySpec.scala:15: inferred view from scala.collection.immutable.IndexedSeq[maqi.Test.Foo] to org.scalacheck.Gen[?] = scalacheck.this.Gen.value[scala.collection.immutable.IndexedSeq[maqi.Test.Foo]]:(x: scala.collection.immutable.IndexedSeq[maqi.Test.Foo])org.scalacheck.Gen[scala.collection.immutable.IndexedSeq[maqi.Test.Foo]] > test [info] Compiling 3 Scala sources to /home/apm/projects/skala-unit-tests/target/scala-2.10/test-classes... [error] /home/apm/projects/skala-unit-tests/src/test/scala/maqi/MySpec.scala:16: overloaded method value forAll with alternatives: [error] (genAndNameA: (org.scalacheck.Gen[maqi.Test.Foo], String),configParams: maqi.Test.sut.PropertyCheckConfigParam*)(fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit [error] (genA: org.scalacheck.Gen[maqi.Test.Foo],configParams: maqi.Test.sut.PropertyCheckConfigParam*)(fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit [error] (nameA: String,configParams: maqi.Test.sut.PropertyCheckConfigParam*)(fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit arbA: org.scalacheck.Arbitrary[maqi.Test.Foo], implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit [error] (fun: maqi.Test.Foo => Unit)(implicit config: maqi.Test.sut.PropertyCheckConfig, implicit arbA: org.scalacheck.Arbitrary[maqi.Test.Foo], implicit shrA: org.scalacheck.Shrink[maqi.Test.Foo])Unit [error] cannot be applied to (scala.collection.immutable.IndexedSeq[maqi.Test.Foo]) [error] sut.forAll[Foo](items) { x => Console println x.i } [error] ^ */ |