2017-04-18 70 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'本身上。每种方法都是避免“静态”模式,同时也避免这些依赖关系。 –