我正在尝试测试
trait Name extends Helper {
def name() = {
var s = getSystem()
s.name()
}
}
我要做的就是确保" s.name()"通过模拟一个s的实例来调用方法,这是一个系统。
助手的定义如下:
trait Helper {
def getSystem() : System = {
systemGetter.get()
}
}
截至目前,我的NameSpec看起来像:
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()时如何在toTest.name()中返回一个模拟系统,以便我可以验证系统只调用一次s.name()。如果它是Name trait中name()方法的参数,我可以很容易地模拟这个系统,所以我想我不知道如何注入"调用该方法时使用的mockSystem代替实际系统。
答案 0 :(得分:0)
不幸的是,您的代码无法编译,因此显然不足以代表您的真实情况。特别是不清楚Helper
如何真正获得System
类型的对象。我认为在实际代码中你应该模拟systemGetter
,我想这是以某种方式注入到实现Helper
特征的对象中,以返回你的mockSystem
。但是,很难根据您提供的代码向您展示有效的示例。如果出于某种原因,这不是你能做的,还有一些途径。
你似乎在Helper
周围使用Cake模式及其继承。如果是这样,您可以使用类而不是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()
}
请注意,您必须为thenCallRealMethod
电话拨打.name()
,因此您应该对name
内的所有电话进行操作,否则测试将无效。