2017-04-18 81 views
0

我有一個Scala對象,它包含一些實用函數。這些函數由同一對象或其他類/對象中存在的其他函數調用。是否有可能嘲笑這個對象或函數,以便我可以單元測試它們被調用的類。嘲笑Scala對象和函數

例子:

object Util { 
 
    
 
    def methodA() = { 
 
    //other code 
 
    methodB() 
 
    //other code 
 
    } 
 
    
 
    def methodB() = { 
 
    //other code 
 
    methodC() 
 
    //other code 
 
    } 
 
    
 
    def methodC() = { ... } 
 

 
}

在這裏,我從另一個類調用該對象的功能

class Data { 
 
    
 
    //other code 
 
    
 
    def call() = { 
 
    //other code 
 
    Util.methodA() 
 
    //other code 
 
    } 
 
}

如何CA ñ我去單元測試類Data的函數調用()?在Java中,我可以爲Util創建一個模擬對象,並設置對methodA()的調用的期望,但這在Scala中是不可能的,因爲沒有模擬庫支持模擬Scala對象。

+0

有許多scala模擬選項。例如,請參閱http://www.scalatest.org/user_guide/testing_with_mock_objects。任何快速搜索都會給你帶來很多選擇 –

+0

是的我已經看到了你提供的鏈接,但是沒有提到的那些模擬框架支持模擬Scala對象。 ScalaMock 2支持模擬對象,但在ScalaMock 3中已經停用,這是Scala 2.11編譯器的最新版本。 – noober

回答

2

從某種意義上說,問題在於您使用的模式與Java中的靜態類相似。你不能嘲笑靜態類,這就是爲什麼Java模式經常不贊成這種方法。

另一方面,在斯卡拉你可以。 Make Util擴展特性並實現它。

trait UtilityMethods { 
def methodA() 
def methodB() 
} 

object Utils extends UtilityMethods { 
    def methodA() = {} 
    def methodB() = {} 
} 

然後在您的測試:

val mockedUtils = mock[UtilityMethods] 

(使用的Mockito)。很明顯,您必須在您的代碼中傳遞UtilityMethods而不是Utils,就像在Java中使用接口一樣。

一般情況下,你也可以使用隱式的作用域沒有靜態類對象的方法注入功能,而嘲笑那些依賴關係,但上面是非常接近的Java模式和應該感到很舒服。

+0

你能舉一個例子顯示如何使用隱式作用域? – noober

+1

當然。有幾種方法可以解決這個問題。我在尋找DI方法時經常使用implicits,因爲它們是相似的模式 - 由外部參與者注入提供的依賴項。在這種情況下,想'類數據(隱含utils的:UtilityMethods)'然後休息如下 - 提供您UtilityMethods的實施方案,其中要求。您也可以使用[隱式類](http://docs.scala-lang.org/overviews/core/implicit-classes.html)將這些方法放在'Data'本身上。每種方法都是避免「靜態」模式,同時也避免這些依賴關係。 –