
The most popular mocking framework for Java, now in Scala!!!
The library has independent developers, release cycle and versioning from core mockito library (https://github.com/mockito/mockito). This is intentional because core Mockito developers don't use Scala and cannot confidently review PRs, and set the vision for the Scala library.
- Artifact identifier: "org.mockito:mockito-scala_2.12:VERSION"
- Latest version - see release notes
- Repositories: Maven Central or JFrog's Bintray
For a more detailed explanation of the features please read this article series
Then mixin one (or both) of the following traits as required
This trait wraps the API available on org.mockito.Mockito
from the Java version, but it provides a more Scala-like syntax, mainly
- Fixes the compiler errors that sometimes occurred when using overloaded methods that use varargs like doReturn
- Eliminates the need to use
classOf[T]
- Eliminates parenthesis when possible to make the test code more readable
- Adds
spyLambda[T]
to allow spying lambdas (they don't work with the standard spy as they are created as final classes by the compiler) - Supports mocking inline mixins like
mock[MyClass with MyTrait]
- Supports by-name arguments in some scenarios EXPERIMENTAL
- Full support when all arguments in a method are by-name
- Full support when only some arguments in a method are by-name, but we use the
any[T]
matcher for every argument - Full support when only some arguments in a method are by-name, but we use NO matchers at all
- Partial support when only some arguments in a method are by-name and we use specific matchers, in this scenario the stubbing will only work if the by-name arguments are the last ones in the method signature
- Adds support for working with default arguments
The companion object also extends the trait to allow the usage of the API without mixing-in the trait in case that's desired
This trait exposes all the existent org.mockito.ArgumentMatchers
but again it gives them a more Scala-like syntax, mainly
eq
was renamed toeqTo
to avoid clashing with the Scalaeq
operator for identity equalityany
resolves to the correct type most of the times, removing the need of using the likes ofanyString
,anyInt
, etcisNull
andisNotNull
are deprecated as using nulls in Scala is clear code smell- Adds support for value classes via
anyVal[T]
andeqToVal[T]()
- Adds
function0
to easily match for a function that returns a given value
Again, the companion object also extends the trait to allow the usage of the API without mixing-in the trait in case that's desired
The matchers for the value classes always require the type to be explicit, apart from that, they should be used as any other matcher, e.g.
when(myObj.myMethod(anyVal[MyValueClass]) thenReturn "something"
myObj.myMethod(MyValueClass(456)) shouldBe "something"
verify(myObj).myMethod(eqToVal[MyValueClass](456))
A new set of classes were added to make it easier, cleaner and more elegant to work with ArgumentCaptors, they also add support to capture value classes without any annoying syntax
There is a new trait org.mockito.captor.ArgCaptor[T]
that exposes a nicer API
Before:
val aMock = mock[Foo]
val captor = argumentCaptor[String]
aMock.stringArgument("it worked!")
verify(aMock).stringArgument(captor.capture())
captor.getValue shouldBe "it worked!"
Now:
val aMock = mock[Foo]
val captor = Captor[String]
aMock.stringArgument("it worked!")
verify(aMock).stringArgument(captor)
captor <-> "it worked!"
As you can see there is no need to call capture()
nor getValue
anymore (although they're still there if you need them)
There is another constructor ValCaptor[T]
that should be used to capture value classes
Both Captor[T]
and ValCaptor[T]
return an instance of ArgCaptor[T]
so the API is the same for both
- by-name arguments is currently an experimental feature as the implementation is a bit hacky and it gave some people problems
If you want to use it, you have to mix-in an extra trait (org.mockito.ByNameExperimental
)
in your test class, after org.mockito.MockitoSugar
, so your test file would look like
class MyTest extends WordSpec with MockitoSugar with ByNameExperimental
It is important to notice that this feature relies on the class loader order to work, as we currently have to override a class
from mockito-core
, you should not have to do anything special to make it work, mockito-scala
already pulls the right
version of mockito-core
as a transitive dependency and it should be the only dependency you need, BUT, if you start getting
weird exceptions while trying to use org.mockito.ByNameExperimental
you can try to be explicit with the mockito-core
dependency.
I can't tell you if you should put it before or after the mockito-scala
dependency in your build file as it depends a lot
on which build tool and IDE you use, so try it out.
We are working with the mockito-core developers to add the necessary features in it so we can get rid of this hack as soon as we can, stay tuned!
- Bruno Bonanno - Initial work - bbonanno
This project is licensed under the MIT License - see the LICENSE file for details