2016-06-01 25 views
5

Giả sử tôi có lớp học này:Kiểm tra chuyển trạng thái có giá trị với 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) 
    } 
} 

Tôi muốn thử nghiệm logic trong canTransitionTo (không bao gồm ở đây vì lợi ích của sự đơn giản) với scalachecks Commands nhưng tôi đang gặp một chút rắc rối về cách bắt đầu. Bất kỳ ý tưởng?

Trả lời

1

some tutorials cách kiểm tra các máy trạng thái với khung này nhưng chúng kiểm tra một thuộc tính khác. Thông thường, họ tạo một Command cho mỗi lần chuyển đổi hợp lệ và kích hoạt scalacheck để thực hiện bất kỳ kết hợp ngẫu nhiên nào trong số chúng. Mục tiêu của thuộc tính này là để xác minh rằng máy trạng thái hoạt động bình thường đối với bất kỳ số lần chuyển tiếp hợp lệ nào.

Cách tiếp cận này sẽ không kiểm tra canTransitionTo vì nó giả định tất cả các hiệu ứng chuyển tiếp đều hợp lệ. Việc kiểm tra quá trình chuyển đổi giữa bất kỳ trạng thái nào sẽ yêu cầu phải thực hiện lại khái niệm về quá trình chuyển đổi hợp lệ và không hợp lệ theo điều khoản của scalacheck. Điều này thậm chí có thể phức tạp hơn sau đó chức năng gốc canTransitionTo.


Nếu một trong các bộ chuyển đổi nhỏ hơn nhiều so với scalacheck khác có thể giúp tạo một bộ chuyển đổi khác. Ví dụ: nếu chỉ có một vài lần chuyển tiếp hợp lệ và thứ mười không hợp lệ thì máy phát điện có thể trợ giúp.

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) 
} 
Các vấn đề liên quan