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

标签 scala testing mocking mockito

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

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

理想情况下,我想将 create 调用 stub ,以便我可以验证它是否被调用,以及参数是否正确。

虽然我是 Mockito 的新手,但我正在尝试拼凑如何在 Scala 中使用它(以及是否可能进行这种测试)。我发现的大多数示例都是用 Java 等语言编写的,不能很好地转换为 Scala。

最佳答案

您可以将 mockito 与 Scala 一起使用。将 mockito 添加到你的库依赖项中(例如,使用 SBT 之类的 libraryDependencies += "org.mockito"% "mockito-core"% "1.8.5"% "test")然后你就设置好了.

如果您正在使用 Scalatest,还有 MockitoSugar,您可以将其作为特征混合或静态导入,为您提供语法糖 mock[ClassToMock] 而不是mockito 的 mock(classOf[ClassToMock])

Mockito 允许您将模拟对象作为外部依赖项传递给“被测单元”,并断言某个方法已被调用。在您的情况下,外部依赖项应该是 messageFactorysmsProvider。但是,后者要求您为 smsProvider 传递 stub 以返回为 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 .

关于Scala 和 mockito 测试 twilio MessageFactory.create() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32936276/

相关文章:

list - 单个列表中的字符串连接

scala - 使用值类(无方法)与类型别名有什么优势?

android - android studio中的junit测试类

c# - 使用 Foq 模拟具有显式实现接口(interface)的类

Grails spock-如何模拟/ stub 类的特定方法

scala - mapreduce Job()抛出了 'java.lang.IllegalStateException'异常。无法评估org.apache.hadoop.mapreduce.Job.toString()

android - lift-json、proguard 和 android

unit-testing - 在测试类中,在断言中使用主题类的常量是个好主意吗?

internet-explorer - IE 中的 Protractor 测试

.net - 模拟 WCF 客户端的 IQueryable 成员