我想使用一些简单的依赖注入和模拟来测试我们的Twilio集成。在我看来,最简单的方法是使用mockito
拦截以下消息create
调用:
val messageFactory: MessageFactory = smsProvider.getAccount().getMessageFactory()
val message: Message = messageFactory.create(params)
理想情况下,我希望将create
调用存根,以便我可以验证它已被调用,并且参数是正确的。
我是Mockito的新手,并尝试拼凑如何在Scala中使用它(如果这种测试甚至是可能的话)。我发现的大多数例子都是Java等,并且不能很好地翻译成Scala。
答案 0 :(得分:2)
您可以在Scala中使用mockito。将mockito添加到您的库依赖项(例如,使用类似libraryDependencies += "org.mockito" % "mockito-core" % "1.8.5" % "test"
的SBT)并重新设置。
如果您正在使用Scalatest,那么MockitoSugar
也可以作为特征混合或静态导入,为您提供语法糖mock[ClassToMock]
而不是模拟&#39 ; s mock(classOf[ClassToMock])
。
Mockito允许您将模拟对象作为外部依赖项传递给您正在测试的单元"并断言某个方法被调用。在您的情况下,外部依赖项应为messageFactory
或smsProvider
。但是,后者要求您传递smsProvider
的存根以返回MessageFactory
的模拟。
您的代码可能如下所示:
import org.mockito.Mockito.verify
import org.mockito.Matchers.any
import org.scalatest.FlatSpec
import org.scalatest.mock.MockitoSugar
// Your Test
class MessageCreatorTest extends FlatSpec with MockitoSugar {
val messageCreator = new MessageCreator
"createMessage" should "create a new message" in {
val factory = mock[MessageFactory]
messageCreator.createMessage(factory)
verify(factory).create(any[List[String]])
}
}
// Your Unit Under Test
class MessageCreator {
def createMessage(messageFactory: MessageFactory): Unit ={
messageFactory.create(List("Foo", "Bar"))
}
}
// The external dependency of your Unit Under Test
trait MessageFactory {
def create(params: List[String]) = new Message("Hello")
}
// A plain value
case class Message(message: String)
但是,如果您的受测单元取决于smsFactory
,您会注意到设置测试会变得更加沉重:
import org.mockito.Mockito.{when, verify}
import org.mockito.Matchers.any
import org.scalatest.FlatSpec
import org.scalatest.mock.MockitoSugar
class MessageCreatorTest extends FlatSpec with MockitoSugar {
val messageCreator = new MessageCreator
"createMessage" should "create a new message" in {
val factory = mock[MessageFactory]
val account = mock[Account]
val smsProvider = mock[SmsProvider]
when(smsProvider.getAccount).thenReturn(account)
when(account.getMessageFactory).thenReturn(factory)
messageCreator.createMessage(smsProvider)
verify(factory).create(any[List[String]])
}
}
class MessageCreator {
def createMessage(smsProvider: SmsProvider): Unit = {
val messageFactory = smsProvider.getAccount.getMessageFactory
messageFactory.create(List("Foo", "Bar"))
}
}
trait MessageFactory {
def create(params: List[String]) = new Message("Hello")
}
case class Message(message: String)
trait SmsProvider {
def getAccount: Account
}
trait Account {
def getMessageFactory: MessageFactory
}
但是,在这种情况下,测试会告诉您,您违反了Law of Demeter。