User Guide - FAQ

FAQ

1. Thread-safety

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

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

2. Limitations of ScalaMock

Can I mock final / private methods or final 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 overriden. You may want to try using an adapter or facade 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, have a look at PowerMock if you really need it. However, it involves Bytecode manipulation, at the risk is that your test double diverges from the actual implementation.


Can I mock val / lazy val?

No, the Scala compiler will not allow overiding 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);
}

Test:

"raw types" should "work" in {
  trait FooB extends Foo {
    override def route(map: util.Map[_, _])
  }
  val m = mock[FooB]
}

Can I mock hashcode, equals 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.


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 to implement a feature to support this as static calls are effectively procedural composition and not good style.