Frequently asked questions

How to convert method to function?

This section answers questions like How can I convert my method to a function so scalamock could use it?.

Method without arguments

Here you should explicitly declare function from ()

class Basic:
  def noArgs: String = "hello"

val basic = Basic()

val noArgsFun = () => basic.noArgs // () => String

Method with arguments

class Basic:
  def oneArg(x: String): String = x.toUpperCase

val basic = Basic()

val oneArgFun = basic.oneArg // String => String

In Scala 2, you need to add _ to convert a method with arguments to a function. Example: myObject.myMethod _

Overloaded method

For overloaded methods - you should explicitly declare types of arguments

class Overloaded:
  def overload(x: Int): Int = 1
  def overload(x: String): Int = 1
  def overload(x: Double, y: Double): Int = 1

val overloaded = Overloaded()

val x = overloaded.overload(_: Int) // Int => Int 
val y = overloaded.overload(_: String) // String => Int
val z = overloaded.overload(_: Double, _: Double) // (Double, Double) => Int

Generic method

For methods with type parameters - you should specify type arguments.

class Generic:
  def example[T](id: String): Option[T] = None

val generic = Generic()

val findUser = generic.example[Int] // String => Option[Int]

Method with varargs

For methods with varargs - the idea is to convert varargs to Seq

class Varargs:
  def example(x: Int*): String = ""
  def example2(x: Int, y: String*): String = ""

val varargs = Varargs()

val x = varargs.example((_: Seq[Int])*) // Seq[Int] => String
val y = varargs.example2(_: Int, (_: Seq[String])*) // (Int, Seq[String]) => String

In Scala 2, you should use : _* instead of * Example: varargs.example((_: Seq[Int]): _*)

Curried method

Curried methods should be converted to uncurried function equivalent

class Multiplier:
  def multiply(x: Int)(y: Int): Int = x * y

val multiplier = Multiplier()

val x = multiplier.multiply(_: Int)(_: Int) // (Int, Int) => Int

Method with context parameters

Methods with context parameters are equivalent to context functions, and we need simple function. To do it - we should explicitly specify using parameter while converting.

class Context:
  def context(x: Int)(using String): String = ""

val ctx = Context()

val x = ctx.context(_: Int)(using _: String) // (Int, String) => String

In Scala 2, implicit parameter is equivalent to plain one, so you don’t need to specify implicit explicitly

What is not mockable?

Scalamock generates a class which extends provided interface, this has few restrictions:

  1. final methods are not mocked, they are just provided as they are
  2. private methods not mocked, they are not available in subclass at all
  3. val and lazy val - can’t be mocked, if they have no implementations - they are assigned to null
  4. object - can’t be mocked since you can’t extend an object
  5. Methods from AnyRef (Object) like equals, hashcode, toString, clone can’t be mocked, they are provided as is
  6. static java methods.

All these features won’t be supported.

Instead, your components must depend on interfaces (traits), not implementations, so you can easily stub/mock them.

Is scalamock thread-safe?

Yes - scalamock is thread-safe.