我有延伸的ScalaTest 2类GeneratorDrivenPropertyChecks
,也间接地延伸FeatureSpec
和Matchers
(经由性状我写延伸这两个类).它有这样的代码:
forAll(mySequence) { myItem => myItem.applicationID should be (foo.applicationID) }
这无法编译,因为scalac说:
[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",意思是这个方法,在GeneratorDrivenpropertyChecks
:
/** * Performs a property check by applying the specified property check function to arguments * supplied by the specified generators. * ** Here's an example: *
* ** 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 the property check function to apply to the generated arguments */ def forAll[A](genA: Gen[A], configParams: PropertyCheckConfigParam*)(fun: (A) => Unit) (implicit config: PropertyCheckConfig, shrA: Shrink[A] ) { // body omitted }
这不是forAll
我想在这里使用的方法!
这是ScalaTest中的错误(即两个方法都不应该被命名forAll
)?
我应该如何调用正确的方法?
这是ScalaTest中的错误吗?
它演示了方法重载的局限性.
在一篇关于无私特质的文章中,Bill Venners将这种模式描述为这些命名冲突的解决方法.
在您的情况下,首选一个重载,因为它在"派生类"中定义.
(我认为;我不是这些测试框架的用户,其中一个源是生成的,所以测试这不是一个简单的问题,即启动sbt并查看代码.)
(编辑:scaladoc说你应该这样做import Inspectors._
.也许你希望继承它.Matchers
因为它也建议导入它的伴侣,虽然这对我来说不合适.如果你这样做import Inspectors._
,你实际上不能通过导入名称.)
(编辑:解释命名位:请参阅规范的第2章的开头,其中它表示名称的绑定具有优先级,并且您继承的名称优先于您导入的名称.)
无论如何,一种解决方案是重新混入Inspectors
,如下所示.
另一种解决方案是使用重命名导入方法:
import Inspectors.{ forAll => iforAll }
尝试选项"-Xprint:typer"," - Xlog-implicit-conversions"来查看正在发生的事情是很有用的.在您的情况下,您的集合通过Gen.value
ScalaCheck 1.10中的隐式视图提升为"常量gen" .
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 } }
一些调试输出:
/* [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 <and> [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 <and> [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 <and> [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] ^ */