Scala和mockito来测试twilio MessageFactory.create()方法

时间:2015-10-04 17:29:28

标签: scala testing mocking mockito

我想使用一些简单的依赖注入和模拟来测试我们的Twilio集成。在我看来,最简单的方法是使用mockito拦截以下消息create调用:

val messageFactory: MessageFactory = smsProvider.getAccount().getMessageFactory()
val message: Message = messageFactory.create(params)

理想情况下,我希望将create调用存根,以便我可以验证它已被调用,并且参数是正确的。

我是Mockito的新手,并尝试拼凑如何在Scala中使用它(如果这种测试甚至是可能的话)。我发现的大多数例子都是Java等,并且不能很好地翻译成Scala。

1 个答案:

答案 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允许您将模拟对象作为外部依赖项传递给您正在测试的单元"并断言某个方法被调用。在您的情况下,外部依赖项应为messageFactorysmsProvider。但是,后者要求您传递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