Suppose I have this class:
class Defaults {
def doSomething(regular: String, default: Option[String] = None) = {
println(s\"Doing something: $regular, $def
This is related with how the Scala compiler implements this as a Java class, remember that Scala runs on the JVM, so everything needs to be transformed to something that looks like Java
In this particular case, what the compiler does is to create a series of hidden methods which will be called something like methodName$default$number where number is the position of the argument this method is representing, then, the compiler will check every time we call this method and if we don’t provide a value for such parameter, it will insert a call to the $default$ method in its place, an example of the “compiled” version would be something like this (note that this is not exactly what the compiler does, but it works for educational purposes)
class Foo {
def bar(noDefault: String, default: String = "default value"): String
}
val aMock = mock[Foo]
aMock.bar("I'm not gonna pass the second argument")
The last line would be compiled as
aMock.bar("I'm not gonna pass the second argument", aMock.bar$default$1)
Now, because we are making the call to bar$default$1
on a mock, and the default behaviour of Mockito is to return null
for anything that hasn’t been stubbed, then what ends up executing is something like
aMock.iHaveSomeDefaultArguments("I'm not gonna pass the second argument", null)
Which is exactly what the error is telling…
In order to solve this some changes have to be made so mockito actually calls the real $default$
methods and so the replacement is done correctly
This work has been done in mockito-scala, so by migrating to that library you'll get a solution for this and many other problems that can be found when mockito is used in Scala
Disclaimer: I'm a developer of mockito-scala