Scala嘲弄由另一个特征扩展的特征
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala嘲弄由另一个特征扩展的特征相关的知识,希望对你有一定的参考价值。
我想测试一下
trait Name extends Helper {
def name() = {
var s = getSystem()
s.name()
}
}
我想要做的就是确保通过模拟s的一个实例来调用“s.name()”方法,这是一个系统。
助手的定义如下:
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而不是一个真实的系统。
答案
不幸的是,您的代码不可编译,因此显然不能代表您真正拥有的代码。特别是不清楚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()
}
注意你必须为thenCallRealMethod
调用调用.name()
,所以你应该对name
中的所有调用执行操作,否则测试将无效。
以上是关于Scala嘲弄由另一个特征扩展的特征的主要内容,如果未能解决你的问题,请参考以下文章