我正在尝试测试
trait Name extends Helper {
def name() = {
var s = getSystem()
s.name()
}
}
我要做的就是确保" s.name()"方法一次通过模拟S系统的实例来调用一次。
助手被定义为:
trait Helper {
def getSystem() : System = {
systemGetter.get()
}
}
截至目前,我的命名Pec看起来像:
class NameSpec extends FlatSpec with Matchers with MockitoSugar {
class NameImpl extends Name
var toTest = new NameImpl
val mockSystem = mock[System]
it should "call s.name() once" in {
when(getSystem() is invoked, return a mockSystem)
toTest.name()
// Verify that mockSystem.name() happened only once
}
}
我感到困惑的是,当调用getSystem()时如何返回模拟系统,以便我可以验证系统仅一次调用s.name()。如果该系统是名称特征中的名称()方法的参数,我可以轻松模拟此系统,因此我想我不知道如何"注入"一个模拟系统,而不是在调用该方法时而不是真实的系统。
不幸的是,您的代码无法编译,因此显然是您真正拥有的代表不足的表示。特别是尚不清楚Helper
如何真正获得System
类型的对象。我认为,在实际代码中,您应该模拟systemGetter
,我想以某种方式注入了实现Helper
特征的对象,以返回您的mockSystem
。但是,很难向您展示一个基于您提供的代码的有效示例。如果由于某种原因这不是您可以做的,那么还有更多的途径。
您似乎使用围绕Helper
及其继承的蛋糕图案之类的东西。如果是这样,您可以使用类而不是NameImpl
注入System
:
class NameWithInjectedSystem(val system: System) extends Name {
override def getSystem(): System = system
}
it should "call s.name() once" in {
val mockSystem = mock[System]
val nameToTest = new NameWithInjectedSystem(mockSystem)
val mockName = "Mock name"
when(mockSystem.name()).thenReturn(mockName)
val actual = nameToTest.name()
actual should === (mockName)
verify(mockSystem, times(1)).name()
}
最后,您甚至可以模拟nameToTest
对象本身,但这不是我建议的方式,因为它将测试绑定到比您想要的更多的实现细节:
it should "call s.name() once" in {
val mockSystem = mock[System]
val nameToTest = mock[NameImpl]
when(nameToTest.getSystem()).thenReturn(mockSystem)
when(nameToTest.name()).thenCallRealMethod()
val mockName = "Mock name"
when(mockSystem.name()).thenReturn(mockName)
val actual = nameToTest.name()
actual should ===(mockName)
verify(mockSystem, times(1)).name()
}
请注意如何调用.name()
调用thenCallRealMethod
,因此您应该对name
内的所有呼叫进行操作或测试将无法使用。