首页 > 解决方案 > 为什么 Mockito verifyNoMoreInteractions 对 Scala 默认值有问题

问题描述

对于一个模拟类,我有一个方法,我想测试是否不再需要交互,它看起来类似于: def someMethod(someMandatoryParam: Int, canBeDefaultIds: Option[Ids] = None): Future[Failures] = {...}

当我在没有默认参数的情况下模拟调用此方法并以这种方式验证它时: verify(someClass).someMethod(someInt) 然后检查是否没有更多交互: verifyNoMoreInteractions(someClass)

我收到一个错误,这里有一些意外的交互。

但是在实现时,我将此方法更改为使用 None 而不是默认值并验证: verify(someClass).someMethod(someInt, None) verifyNoMoreInteractions(someClass)

它工作正常。

Mocikto 和 Scala 中的默认值有问题吗?

标签: scalamockingmockito

解决方案


默认参数是 Java Mockito 可能不知道的 Scala 特定功能。考虑 Scala 代码在-Xprint:jvm阶段后的样子

abstract trait SomeClass extends Object {
  def someInt(a: Option): Option = a;
  <synthetic> def someInt$default$1(): Option = scala.None;
}

注意默认参数是如何变成另一种方法someInt$default$1的。尝试使用考虑到 Scala 设计的mockito-scala ,例如以下测试通过

import org.mockito.{ArgumentMatchersSugar, IdiomaticMockito}
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

trait SomeClass {
  def someInt(a: Option[Int] = None) = a
}

class MockitoScalaDefaultArgsSpec extends AnyFlatSpec with Matchers with IdiomaticMockito with ArgumentMatchersSugar {
  "mockito-scala" should "handle default arguments" in {
    val someClass = mock[SomeClass]
    someClass.someInt()
    someClass.someInt() was called
    someClass wasNever calledAgain
  }
}

推荐阅读