2016-06-01 17 views
5

Supponiamo che io ho questa classe:prova transizioni di stato validi con ScalaCheck

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) 
    } 
} 

mi piacerebbe testare la logica in canTransitionTo (non incluso qui per semplicità) con scalachecks comandi ma sto avendo un po 'di problemi su come iniziare. Qualche idea?

risposta

1

Ci sono some tutorials come testare le macchine di stato con questo framework ma testano un'altra proprietà. Di solito creano uno Command per ogni transizione valida e sparano scalacheck per fare qualsiasi combinazione casuale di essi. L'obiettivo di tale proprietà è verificare che la macchina di stato si comporti normalmente per un numero qualsiasi di transizioni valide.

Questo approccio non testerà canTransitionTo perché presuppone che tutte le transizioni siano valide. Per verificare le transizioni tra qualsiasi coppia di stati sarà necessario reimplementare una nozione di transizioni valide e non valide in termini di scalacheck. Questo potrebbe essere ancora più complesso della funzione originale canTransitionTo.


Se uno dei gruppi di transizione è molto più piccolo rispetto alle altre scalacheck può aiutare a generare un altro. Ad esempio, se ci sono solo poche transizioni valide e un decimo di invalidi, i generatori possono essere d'aiuto.

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) 
} 
Problemi correlati