Smockito is a tiny framework-agnostic Scala 3 facade for Mockito. It enables setting up unique method and value stubs for any type in a type-safe manner, while providing an expressive interface for inspecting received arguments and call counts.
Head to the microsite for the full documentation and API reference.
To use Smockito in an existing sbt project with Scala 3, add the following dependency to your
build.sbt:
libraryDependencies += "com.bdmendes" %% "smockito" % "<version>" % TestDo not depend on Mockito directly.
If targeting Java 24+, you need to add the Smockito JAR as a Java agent to enable the runtime bytecode manipulation that Mockito depends on. If you use the sbt-javaagent plugin, you can simply add to your build.sbt:
javaAgents += "com.bdmendes" % "smockito_3" % "<version>" % TestIn your specification, extend Smockito. This will bring the mock method and relevant conversions to scope. To set up a mock, add stub definitions with the on method, which requires an eta-expanded method reference, that you may easily express with it, and a partial function to handle the relevant inputs.
abstract class Repository[T](val name: String):
def getWith(startsWith: String, endsWith: String): List[T]
case class User(username: String)
class RepositorySpecification extends Smockito:
val repository = mock[Repository[User]]
.on(it.getWith):
case ("john", name) if name.nonEmpty => List(User("johndoe"))A Mock[T] is a T both at compile time and runtime.
assert(repository.getWith("john", "doe") == List(User("johndoe")))You may reason about method interactions with calls and times. If arguments are not needed, times is more efficient.
assert(repository.calls(it.getWith) == List(("john", "doe")))
assert(repository.times(it.getWith) == 1)