我正在尝试测试Object.method
,其中包含来自Trait
的一些嵌套方法以及一些计算。这些嵌套方法必须被模拟(它们访问数据库,所以我想模拟它们的响应)。
当我调用真实的Object.method
时,它应该跳过嵌套方法的调用并检索我想要的内容。我曾尝试嘲笑它们,但测试仍在称呼他们。
这是我的示例源代码:
trait MyTrait {
def myMethodToMock(a: String): String
}
object MyObject extends MyTrait {
def myParentMethod(a:String) = {
val b = myMethodToMock(a)
val c = a + b
c
}
}
然后在我的测试中:
val myTraitMock = mock[MyTrait]
when(myTraitMock.myMethodToMock(a)).thenReturn(b)
//Then I call the parent method:
assert(MyObject.myParentMethod(a) equals c)
它仍在访问myMethodToMock
答案 0 :(得分:3)
您的代码无法编译,因此我将猜测您在此处实际尝试执行的操作...
您要在模拟中添加方法,然后在完全不相关的实例上调用它。难怪它不起作用。
一个好的经验法则(以及最佳实践)是永远不要模拟您实际上正在测试的类。将要模拟和测试的所有内容分别拆分到一个单独的类中。这也称为单一责任原则(每个组件应对一件事情负责)。
trait MyTrait {
def myMethodToMock(a: String): String
}
object MyTrait extends MyTrait {
def myMethodtoMock(a: String) = ???
}
class MyObject(helper: MyTrait = MyTrait) {
def myParentMethod(a: String) = a + helper.myMethodToMock(a)
}
object MyObject extends MyObject()
现在,您可以像这样编写测试:
val myTraitMock = mock[MyTrait]
when(myTraitMock.myMethodToMock(any)).thenReturn("b")
new MyObject(myTraitMock).myParentMethod("a") shouldBe "ab"
verify(myTraitMock).myMethodToMock("a")
此处的主要区别在于,您要将模拟传递到对象的构造函数中,以便在调用该方法时,它将成为您的方法,而不是默认类提供的实现。
答案 1 :(得分:0)
您应该使用合成而不是继承,以便可以注入MyTrait
的实例,该实例可以是模拟的也可以是真实的