如何通过模拟嵌套方法来测试方法



我正在尝试测试一个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)

它抛出一个 NullPointerException,因为它仍在访问myMethodToMock

你的代码无法编译,所以我要猜测你在这里实际尝试做的一些事情......

您正在模拟上存根一个方法,然后在一个完全不相关的实例上调用它。难怪它不起作用。

一个好的经验法则(也是最佳实践(是永远不要模拟你实际测试的课程。将要模拟和测试的所有内容单独拆分到一个单独的类中。这也称为单一责任原则(每个组件应该负责一件事(。

 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")

这里的主要区别在于,您将模拟传递到对象的构造函数中,因此当它调用该方法时,它将是您存根的那个,而不是默认类提供的实现。

你应该使用组合而不是继承,所以你可以注入一个MyTrait的实例,它可以是模拟的或真实的

相关内容

  • 没有找到相关文章

最新更新