2017-02-14 55 views
2

我有Double值在價值上相似,但不是確切的。通常情況下,我會做:Scalatest案例類別清單中的雙等同案件

val a: Double = ??? 
val b: Double = ??? 

a shouldEqual b +- 0.25 

如果我只是比較單一的情況下類,我會做:

case class Data(label: String, value: Double) 
val a: Data = ??? 
val b: Data = ??? 
a.value shouldEqual b.value +- 0.25 

在我的情況,我有case類實例的列表,並想用比較寬容他們的value屬性:

val output = Seq(Data("a", 1.1), Data("b", 1.2)) 
val expected = Seq(Data("a", 0.9), Data("b", 1.1)) 
output should contain theSameElementsInOrderAs expected 

當然,這會文件,因爲value屬性不完全匹配。我需要的是這樣的:

output should contain theSameElementsInOrderAs expected +- 0.25 

回答

0

我結束了定義自定義MatcherSeq[Data]類型:

trait CustomMatcher { 

    class SeqDataContainsTheSameElementsInOrderAs(expected: Seq[Data]) { 

    override def apply(left: Seq[Data]): MatchResult = { 

     // ... do other checks like comparing the length and such 

     val bad = left.zip(expected).filter(t => { 
     val difference = Math.abs(t._1.value - t._2.value) 
     difference > TOLERANCE // Declare this somewhere 
     }) 

     // Return the MatchResult, you will probably want to give better error messages than this 
     MatchResult(
     bad.isEmpty, 
     s"""Some of the values were not equal""", 
     s"""Everything was equal""" 
    ) 
    } 

    def customContainTheSameElementsInOrderAs(expected: Seq[Data]) = new SeqDataContainsTheSameElementsInOrderAs(expected) 
    } 
} 

然後我用它喜歡:

output should customContainTheSameElementsInOrderAs(expected) 
0

你可以只去

forAll(output.zipAll(expected, null, null)) { 
    case (a, b) => a.value shouldEqual b.value +- 0.25 
} 

使用zipAll因爲zip會錯誤地成功時的長度不匹配,但錯誤信息你會得到這樣ISN太不好。