User Guide - FAQ

FAQ

Is ScalaMock thread-safe? Can mocks be used in a multi-threaded environment?

Yes - ScalaMock is thread-safe and mocks can be used in a multi-threaded environment. This means that:


Can I mock final / private methods or classes?

This is not supported, as mocks generated with macros are implemented as subclasses of the type to mock. So private and final methods cannot be overridden. You may want to try using an adapter or façade in your code to make it testable. It is better to test against a trait/interface instead of a concrete implementation. There are libraries that support this kind of mocking, such as PowerMock. Be aware that this kind of mocking involves Bytecode manipulation, which has the risk that your test double diverges from the actual implementation.


Can I mock val / lazy val?

No, the Scala compiler will not allow overriding a val with a def, so with ScalaMock this is not possible. An option we are looking at for a possible future verion of ScalaMock is scala.meta, but this is not yet available for all build targets we want. If you can, it is better to design a trait with a def and mock that instead. The concrete implementation can still override that def with a val to give invariant behaviour.


Can I mock objects?

No, macros cannot generate a subclass of a singleton object, sorry. A way to refactor your code may be to create a trait with the function(s) you want to mock and extend that with the object. Or use Dependency Injection (with classes or functions) to abstract your code and make it testable.


Can I mock Java APIs with raw types?

Yes - but you will need a bit of boilerplate. Here is an example:

import java.util.Map;

public interface Foo {
    public void route2(Map<String, Integer> map);
    public void route(Map map);
}
"raw types" should "work" in {
  trait FooB extends Foo {
    override def route(map: util.Map[_, _])
  }
  val m = mock[FooB]
}

Can I mock hashcode, equals, clone or toString ?

No - all methods from java.lang.Object are filtered out during Mock creation. toString is particularly problematic as it can cause an infinite loop blowing up the stack on test failure.

If your interface requires you to implement clone for example, you can create a mock like this:

interface Resource {
    public Resource clone(String cloneName);
}
abstract class MockableResource extends Resource {
  override def clone(cloneName: String): Resource = ???
}

// ...

val resource: Resource = mock[MockableResource]

Can I mock static Java calls?

We recommend you use Dependency Injection, higher-order functions or OO patterns (interfaces, facades, etc) instead of depending directly of implementations. We are not considering adding support for this feature as static calls are effectively procedural composition and not good style.