2017-12-04 7 views
0

상태 저장 테스트를 위해 Scalacheck documentation에서 ATM maschine은 유스 케이스로 언급됩니다. 작동하려면 명령에 매개 변수 (예 : PIN 또는 인출 금액)가 필요합니다. 주어진 예제에서 클래스 Counter의 메소드에는 매개 변수가 없습니다. 명령의Scalacheck - 명령에 매개 변수 추가

class Counter { 
    private var n = 0 
    def inc(i: Int) = n += i 
    ... 
} 

runnextState 방법 매개 변수를 제공하지 않습니다 :

이제 내 질문에 내가 scalachecks이 같은 상태 테스트를하는 방법을 테스트 할 수있는 방법입니다. Sut에 매개 변수를 전달하는 방법이

case object Inc extends UnitCommand { 
    def run(sut: Sut): Unit = sut.inc(Random.nextInt) 

    def nextState(state: State): State = state + Random.nextInt 
    ... 
} 

있습니까 : runnextState의 값이 다를 것이며, 테스트가 실패하기 때문에하는 Random.nextInt 작동하지 않을 추가? 어떻게 genCommand에서 알 수있는 바와 같이

답변

1

는 ScalaCheck Commands 실제로 초기 genInitialState에 의해 생성 된 상태 및 genCommand에 의해 생성 된 명령의 시리즈 사이에 데카르트 제품과 같은 작업을 수행합니다. 따라서 일부 명령에 실제로 매개 변수가 필요한 경우 매개 변수를 객체의 클래스로 변환하고 매개 변수로 Gen을 제공해야합니다. 그래서이 같은 필요합니다 문서에서 예제를 수정 : (PIN 코드의 경우에서와 같이) 귀하의 매개 변수 인 경우 그냥 변수가 아니라 상수 것을

/** A generator that, given the current abstract state, should produce 
    * a suitable Command instance. */ 
def genCommand(state: State): Gen[Command] = { 
    val incGen = for (v <- arbitrary[Int]) yield Inc(v) 
    val decGen = for (v <- arbitrary[Int]) yield Dec(v) 
    Gen.oneOf(incGen, decGen, Gen.oneOf(Get, Reset)) 
} 

// A UnitCommand is a command that doesn't produce a result 
case class Inc(dif: Int) extends UnitCommand { 
    def run(sut: Sut): Unit = sut.inc(dif) 

    def nextState(state: State): State = state + dif 

    // This command has no preconditions 
    def preCondition(state: State): Boolean = true 

    // This command should always succeed (never throw an exception) 
    def postCondition(state: State, success: Boolean): Prop = success 
} 

case class Dec(dif: Int) extends UnitCommand { 
    def run(sut: Sut): Unit = sut.dec(dif) 

    def nextState(state: State): State = state - dif 

    def preCondition(state: State): Boolean = true 

    def postCondition(state: State, success: Boolean): Prop = success 
} 

주, 당신은해야하거나 하드 코드 그것들을 명령으로 사용하거나 객체가 아닌 전체 명세 클래스를 만들고 그 매개 변수를 외부에서 전달하십시오.

+0

고맙습니다.이 솔루션은 내가 찾던 해결책처럼 보입니다! – amuttsch