2016-06-01 16 views
5

가정하자 나는이 클래스가 :테스트 유효한 상태 전환은

case class Receipt(id: Long, state: String) { 
    def transitionTo(newState: String) = { 
    if (!canTransitionTo(newState)) { 
     throw new IllegalStateExcetion(s"cant transition from $state to $newState") 
    } 
    this.copy(state = newState) 
    } 
} 

내가 scalachecks 명령을 사용하여 canTransitionTo의 논리 (안 간단하게하기 위해 여기에 포함)를 테스트하고 싶습니다하지만 난 데 시작하는 방법에 약간의 문제. 어떤 아이디어?

답변

1

이 프레임 워크로 상태 머신을 테스트하는 방법은 some tutorials이지만 다른 속성을 테스트합니다. 일반적으로 그들은 각각의 유효한 전환에 대해 Command을 생성하고 scalacheck을 발사하여 임의의 조합을 수행합니다. 이러한 속성의 목적은 상태 머신이 여러 번 유효한 전환에 대해 정상적으로 작동하는지 확인하는 것입니다.

이 방법은 모든 전환이 유효하다고 가정하기 때문에 canTransitionTo을 테스트하지 않습니다. 어떤 상태 쌍 사이의 전이를 테스트하려면 scalacheck의 관점에서 유효하고 무효 한 전이 개념을 다시 구현해야합니다. 이것은 원래의 canTransitionTo 기능보다 더 복잡 할 수 있습니다.


전환 세트 중 하나가 다른 하나를 생성하는 데 도움이 될 수 있습니다 scalacheck 다른보다 훨씬 작은 경우. 예를 들어 유효 전환이 소수이고 유효하지 않은 경우가 10 분이면 발전기가 도움이 될 수 있습니다.

private val allStates: Gen[String] = Gen.oneOf("State1", "State2", "State3") 

private val validTransitions: Set[(String, String)] = Set("State1" -> "State2", "State2" -> "State3", "State3" -> "State1") 
private val validTransitionsGen: Gen[(String, String)] = Gen.oneOf(validTransitions.toSeq) 

private val invalidTransition: Gen[(String, String)] = for { 
    from <- allStates 
    to <- allStates 
    if !validTransitions.contains(from -> to) //this is reimplementaion of canTransitionTo 
} yield from -> to 

property("valid transitions") = forAll(validTransitionsGen) { transition => 
    Receipt(0, transition._1).canTransitionTo(transition._2) 
} 

property("invalid transitions") = forAll(invalidTransition) { transition => 
    !Receipt(0, transition._1).canTransitionTo(transition._2) 
}