2016-09-30 86 views
1

我有一個單元測試,它測試了一些解決方案。但是這個測試代碼也可以用於測試其他非常類似的解決方案。我想提出的是測試的代碼是通用的被應用到這兩種解決方案,如:使用類型參數寫入函數

describe("when table contains all correct rows") { 
     it("should be empty") { 
     def check[T](func: T => List[Row]) = { 
      val tableGen = new TableGenerator() 
      val table: Vector[Row] = tableGen.randomTable(100) 
      .sortWith(_.time isBefore _.time).distinct 
      val result: List[Row] = func(table) 
      assert(result.isEmpty) 
     } 

     check(Solution.solution1) 
     check(Solution.solution2) 
     } 
    } 

其中的解決方案有兩類:

solution1: IndexedSeq[Row] => List[Row] 
solution2: Seq[Row] => List[Row] 

如何檢查()函數必須寫成能夠做到這一點? 什麼是最好的方法來寫這個(可能以其他方式)與消除代碼重複?

更新: 當我嘗試編譯這段代碼,我得到類型不匹配的錯誤func(table)

Error:(36, 29) type mismatch; 
found : table.type (with underlying type scala.collection.immutable.Vector[com.vmalov.tinkoff.Row]) 
required: T 
      val result = func(table) 
+0

爲什麼你認爲你需要做什麼嗎?這個'check'函數應該已經可以做到這一點,並且沒有重複的代碼在你展示的內容中被消除。 –

+0

一旦我試圖編譯我得到類型不匹配的錯誤:發現矢量[行],需要T(表我傳遞給func)。 第二個問題是關於可能存在另一個更好/更可靠的方法來抽象這樣的事情。 – likern

+0

你應該在問題中加上。 –

回答

4

對於這個工作,你需要能夠通過一個Vector[Row]func,所以任何Vector[Row]必須是一個T;即TVector[Row]的超類型。您可以通過使用類型參數限制這個告訴編譯器:

def check[T >: Vector[Row]](func: T => List[Row]) 

或者,由上述推理,功能T => List[Row]也將是一個功能Vector[Row] => List[Row]正是當TVector[Row]的超類型,以及Scala編譯器知道這個(功能是反變換在他們的參數類型(s))。所以這個簽名等同於簡單的

def check(func: Vector[Row] => List[Row]) 

當然,你可以概括這一點,但多少要看您的具體願望。例如。您可以替換List[Row]Seq[Row](無處不在),或與一類參數,並通過一個額外的功能check

def check[A](func: Vector[Row] => A)(test: A => Boolean) = { 
    val table = ... 
    val result = func(table) 
    assert(test(result)) 
} 

check(Solution.solution1)(_.isEmpty) // the compiler infers A is List[Row] 
+0

非常感謝!這正是我想要的。 – likern

3

你的話,也許就足以抽象的一個更具體的方式類型,比如界定你期待着一個Travesable。

def check[S[_] : Traversable](func: S[Row] => List[Row]) 

這將接受Seq或IndexedSeq作爲有效參數,同時它也限制它。

我希望它能幫助

編輯:檢查阿列克謝·羅曼諾夫回答,因爲有了這個,你將無法FUNC你做的方式來調用。比較遺憾的是

高清檢查(FUNC:矢量[行] =>列表[行])

+0

我想你是指'S [X] <:可穿越[X]'。 –

+0

這似乎沒有解決這個問題,我太快地回答:P但Alexey Romanov似乎已經很好地回答了這個問題。 – FerranJr

+0

感謝您的回覆。但的確,這並不能解決問題。 – likern