2016-12-12 111 views
3

我想重構一些使用隱式類的代碼。 基本上,它是一些單元測試的代碼,我在其中使用Mockito進行一些模擬和間諜活動。斯卡拉隱式類和函數

在下面的實例中,這些功能的嘲笑在隱式類A.每個方法「overrideX」需要一個預期的結果完成後,將覆蓋在調用方法中的X MyObj中並返回MyObj中(爲了便於鏈接多個生成器模式之後覆蓋)。

object Outer { 
    "call to abc" should { 
    "fail if call to X fails" in { 
     val failReason = "X failed" 
     val myObjMock = B 

     myObjMock.overrideX(failReason) 
     myObjMock.abc mustEqual failReason 
    } 

    "fail if call to Y fails" in { 
     val failReason = "Y failed" 
     val myObjMock = B 

     myObjMock.overrideY(failReason) 
     myObjMock.abc mustEqual failReason 
    } 
    } 

    implicit class A(myObj: B) { 
    def overrideX(result: Result): B = { 
     //override call to X in myObj with result 
     myObj 
    } 

    def overrideY(result: Result): B = { 
     //override call to Y in myObj with result 
     myObj 
    } 
    } 
}  

我試圖解決的問題是在測試中消除了大量的鍋爐板。正如你在上面的例子中看到的那樣,這兩個測試看起來非常相似。 我想實現的是創建一些通用的方法,這兩種方法都採用覆蓋方法並進行實際檢查。

def somethingElse(result: Result, f: Result => B) = { 
    val myObjMock = B 
    myObjMock.f(result).abc mustEqual result 
} 

測試看起來像

"call to abc" should { 
    "fail if call to X fails" in { 
     val failReason = "X failed" 
     somethingElse(failReason, overrideX) 
    } 

    "fail if call to Y fails" in { 
     val failReason = "Y failed" 
     somethingElse(failReason, overrideY) 
    } 
    } 

我知道overrideX和overrideY方法是在類,而不是一個同伴對象。

我目前有一個版本,其中的overrideXX方法在伴隨對象中,並將結果和驗證器作爲參數。但他們不是隱含的,我不得不放棄建設者的模式,所以不要束縛他們。

回答

2

我覺得你需要的是一個函數(B, Result) => B而不是Result => B。如果變量f包含一個函數,則不能在像myObjMock.f(...)這樣的對象上調用它。但你可以通過myObjMockf,如f(myObjMock, ...)

def somethingElse(result: Result, f: (B, Result) => B) = { 
    val myObjMock = B 
    f(myObjMock, result).abc mustEqual result 
} 

"call to abc" should { 
    "fail if call to X fails" in { 
    val failReason = "X failed" 
    somethingElse(failReason, _.overrideX(_)) 
    } 

    "fail if call to Y fails" in { 
    val failReason = "Y failed" 
    somethingElse(failReason, _.overrideY(_)) 
    } 
} 
+0

非常感謝。奇蹟般有效。直到現在還不知道_.methodCall(_)的東西。 –