imaru
imaru

Reputation: 47

Why does Mockito verifyNoMoreInteractions has problem with Scala default values

For a mocked class I have a method for which I would like to test whether there are no more interactions then needed, which looks similar to: def someMethod(someMandatoryParam: Int, canBeDefaultIds: Option[Ids] = None): Future[Failures] = {...}

when I am mocking to invoke this method without the default parameter and I verify it that way: verify(someClass).someMethod(someInt) and then check if there was no more interactions: verifyNoMoreInteractions(someClass)

I am getting an error that here was some unexpected interactions.

But when in implementation I change this method to use None instead of default value and verify: verify(someClass).someMethod(someInt, None) verifyNoMoreInteractions(someClass)

It works correctly.

Is there a problem with Mocikto and default values in Scala?

Upvotes: 1

Views: 500

Answers (1)

Mario Galic
Mario Galic

Reputation: 48410

Default arguments is Scala specific feature which Java Mockito is likely not aware of. Consider how Scala code looks after -Xprint:jvm phase

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

Notice how the default argument became just another method someInt$default$1. Try using mockito-scala which is designed with Scala in mind, for example the following test passes

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
  }
}

Upvotes: 1

Related Questions