我有一个看起来像这样的课程:
class EpidemySimulator extends Simulator {
...
class Person{
// Implementation
}
}
我想添加一个内部类Persons的Arbitrary,以便我可以在EpidemySimulator类上定义一些属性。我认为伴随对象可以定义所需的隐式生成器,以便定义将生成Person类型对象的属性。
object EpidemySimulator
{
implicit def arbPerson(implicit sim: EpidemySimulator ) =
Arbitrary(for(n <- Gen.choose(1, roomRows * roomColumns))yield{ new sim.Person(n) })
def propertyOne(sim: EpidemySimulator ) = forAll { person: sim.Person =>
person.row > 0 && person.row < roomRows && person.col > 0 && person.col < roomColumns
}
}
我的理解是,如果我提供隐式函数,在给定特定Arbitrary[sim.Person]
(隐式提供)的情况下创建sim:EpidemySimulator
,那么我应该能够在propertyOne
中创建属性。但是我在属性上遇到编译器错误,说
Multiple markers at this line
- identifier expected but ';' found.
- not enough arguments for method forAll: (implicit p: Boolean => org.scalacheck.Prop, implicit a1: org.scalacheck.Arbitrary[sim.Person],
implicit s1: org.scalacheck.Shrink[sim.Person], implicit pp1: sim.Person => org.scalacheck.Pretty)org.scalacheck.Prop. Unspecified value parameters
a1, s1, pp1.
- could not find implicit value for parameter a1: org.scalacheck.Arbitrary[sim.Person]
- type <error> is not a member of simulations.EpidemySimulator
任何想法我做错了什么。我希望最终能够:
class EpidemySuite extends FunSuite with Checkers {
test("EpidemySimulator fulfills property one"){
val es = new EpidemySimulator
check( EpidemySimulator.propertyOne(sim) )
}
}
答案 0 :(得分:1)
我认为问题如下:你提供了一个隐含的生成一个任意的EpidemySimulator#Person给定一个EpidemySimulator。
implicit def arbPerson(implicit sim: EpidemySimulator ) =
Arbitrary(for(n <- Gen.choose(1, roomRows * roomColumns))yield{ new sim.Person(n) })
但是在EpidemySimulator的测试中,没有EpidemySimulator类型的隐式值可用,因此上面隐含的一个人不能使用。使sim隐式或定义localmySimulator类型的本地隐式应该解决问题
def propertyOne(implicit sim: EpidemySimulator ) = forAll { person: sim.Person =>
person.row > 0 && person.row < roomRows && person.col > 0 && person.col < roomColumns
}
鉴于您可能想要测试EpidemySimulator的各种属性,在对象中的某处定义隐式的epidemySimulator val可能是个好主意。
请注意,我只使用scala控制台会话检查了这些内容,如下所示:
import org.scalacheck._
import org.scalacheck.Prop.forAll
// define a class with an inner class
class A { class B }
// define an implicit that provides a A#B given an A
implicit def arbAB(implicit a:A) : Arbitrary[a.B] = Arbitrary[a.B] { new a.B }
// the non-working code
def test(a:A) = forAll { x:a.B => true }
<console>:25: error: could not find implicit value for parameter a1: org.scalacheck.Arbitrary[a.B]
def test(a:A) = forAll { x:a.B => true }
^
// making a an implicit works
def test(implicit a:A) = forAll { x:a.B => true }