Scala中对象的Mockito
我正在使用Scala 2.10、specs2和Mockito。我想模拟scala.io.Source.fromURL()。问题似乎在于fromURL()是中的一个函数 这是单元测试中非常简单的模拟。为什么不起作用Scala中对象的Mockito,scala,object,mockito,Scala,Object,Mockito,我正在使用Scala 2.10、specs2和Mockito。我想模拟scala.io.Source.fromURL()。问题似乎在于fromURL()是中的一个函数 这是单元测试中非常简单的模拟。为什么不起作用 谢谢 您可以按如下方式尝试监视它,而不是模拟它: val m = spy(io.Source) val m = mock[io.Source.type] 或者你也可以这样嘲笑它: val m = spy(io.Source) val m = mock[io.Source.type
谢谢 您可以按如下方式尝试
监视它,而不是模拟它:
val m = spy(io.Source)
val m = mock[io.Source.type]
或者你也可以这样嘲笑它:
val m = spy(io.Source)
val m = mock[io.Source.type]
但是,您如何在正在测试的类中使用源代码?如果您有这样一个示例类:
class MyClass{
def foo = {
io.Source.doSomething //I know doSomething is not on Source, call not important
}
}
class MyClass{
val source = io.Source
def foo = {
source.doSomething
}
}
然后,为了利用模拟/监视,您必须按照如下方式构造类:
class MyClass{
def foo = {
io.Source.doSomething //I know doSomething is not on Source, call not important
}
}
class MyClass{
val source = io.Source
def foo = {
source.doSomething
}
}
然后你的测试应该是这样的:
val mockSource = mock[io.Source.type]
val toTest = new MyClass{
override val source = mockSource
}
在Java世界中,静态方法是模仿的祸根。在Scala世界中,对对象的调用对于单元测试来说也很麻烦。但是,如果您遵循上面的代码,您应该能够在类中正确地模拟出基于对象的依赖关系。几年后,上述答案并不像其他人指出的那样有效
然后,您将看到scala.io.Source
对象
我可以模拟final/private方法或类吗?这是不受支持的,因为使用宏生成的mock被实现为mock类型的子类。因此,不能重写私有方法和final方法。您可能希望尝试在代码中使用适配器或façade使其可测试。最好针对trait/接口而不是具体的实现进行测试。有些库支持这种模拟,例如PowerMock。请注意,这种模拟涉及字节码操作,这有可能使您的测试与实际实现产生偏差
因此,我所做的是将scala.io.Source.fromUrl()抽象为函数参数,并在测试中传入模拟函数
//原始函数
def afuncthatsusesource()={
val source=scala.io.source(“127.0.0.1:8080/…”)
val result=source.mkString
尝试(source.close())
结果
}
//接受'scala.io.Source.fromURL'作为参数的测试友好函数
def aTestFriendlyFunc(makeApiCall:String=>BufferedSource)={
val source=makeApiCall(“127.0.0.1:8080/…”)
val result=source.mkString
尝试(source.close())
结果
}
....
//测试规范
def testyMcTesterson=()=>{
val makeApiCall=mockFunction[字符串,缓冲源]
makeApiCall.expected(“某物…”)
.returns(new BufferedSource(new ByteArrayInputStream(“returns something”.getBytes)))
aTestFriendlyFunc(makeApiCall)应等于“返回某物”
}
好消息!使用最新的1.16版本的mockitoscala
,您现在可以模拟scalaobject
s
要启用withObjectMocked功能,必须创建文件src/test/resources/mockito extensions/org.mockito.plugins.MockMaker,其中包含一行:
mock-maker-inline
例如:
objectfoooobject{
def simpleMethod:String=“未模拟!”
}
“模拟”应该是{
中的“存根对象方法”{
FooObject.simpleMethod应该是“不被嘲笑!”
withObjectMocked[FooObject.type]{
FooObject.simpleMethod返回“mocked!”
//或
当(FooObject.simpleMethod)返回“mocked!”
FooObject.simpleMethod应该是“mocked!”
}
FooObject.simpleMethod应该是“不被嘲笑!”
}
}
请参阅:回答得很好!我是Scala的新手,我觉得它很麻烦。正如一位朋友所说,它看起来类似于依赖注入模式。为什么模仿io.BufferedSource的mkString不起作用?这是一个实例方法:我得到一个错误:Mockito无法模拟/间谍以下:-最终类-匿名类-原语类型是否可以对对象执行类似操作?嘿@GismoRanas如何解决此问题我面临相同的错误。这与PowerMock模拟静态的方式不同;后者通过修改原始对象的字节码来实现,而在我的测试中,似乎withObjectMocked
通过子类化创建了一个新实例。除非注入对mock的引用,否则测试中的代码仍将引用原始对象。