【问题标题】:How to mock arbitrary blocks of code in Mockito Scala?如何在 Mockito Scala 中模拟任意代码块?
【发布时间】:2018-04-25 02:16:46
【问题描述】:

所以我有以下代码

class MetricsLogger {

  def measure[T](name:String)(operation: => T): T = {
      val startTime = System.currentTimeMillis
      val result = try {
        operation
       } finally {
        logMetric(Metric(name, System.currentTimeMillis - startTime, StandardUnit.Milliseconds))
      }
      result
  }
}

日志指标是某种副作用(例如,将指标上传到 cloudwatch)。

现在我正在这样做

def measuredOp = measure("metricName") { someOperation }

这里的一些操作是进行一些网络调用。

现在我必须存根测量的操作。

所以我的存根如下:-

val loggingMetrics = mock[MetricsLogger] // mock is from MockitoSugar trait

我的存根就像

 Mockito.when(loggingMetrics.measure(Matchers.anyString())(Matchers.anyObject())).thenReturn(???)

很明显我的存根是错误的,但我不知道如何正确地存根。

【问题讨论】:

  • 我不确定这可以用 Mockito 来完成——按名称参数和多个参数列表的组合使得这特别棘手。可能可以使用 ScalaMock - 请参阅此处的讨论:groups.google.com/forum/#!topic/specs2-users/dd_LXkQMJvo
  • 在测试对象创建期间覆盖此方法而不是模拟。
  • 这对我来说看起来不错...这里有什么问题? .thenReturn 块只需要返回正确的返回类型(在这种情况下可能是一个对象?)。我个人更喜欢使用ArgumentMatchers 而不是Matchers,但这只是我的偏好。你认为你的存根有什么问题?
  • @JamesWhiteley - 对于初学者来说是不完整的。我也无法调和:=> T 和 ret T。

标签: scala mockito


【解决方案1】:

Mockito 不支持将其作为名称参数,这是 Java 中不存在的概念,但是,mockito-scala 从 0.4.0 版本开始支持此功能(尝试 0.4.0 或 0.4.2,忽略 0.4 .1)

我只是像这样运行一个快速测试

import org.mockito.{ MockitoSugar, ArgumentMatchersSugar }

class StackOverflowTest extends WordSpec with MockitoSugar with scalatest.Matchers with ArgumentMatchersSugar {

  "mock[T]" should {

    "it should work with by-name params" in {
      val loggingMetrics = mock[MetricsLogger]

      when(loggingMetrics.measure(any)(any)).thenReturn("it worked!")

      loggingMetrics.measure("test")("") shouldBe "it worked!"
    }
  }
}

免责声明:我是该库的维护者,尽管它是官方 Mockito 套件的一部分

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-02
    • 2016-12-25
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多