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:
- ScalaMock will work with tests that are run in parallel
- Specs2 runs tests in parallel by default and
- ScalaTest does so with
ParallelTestExecution
- You can call mocks from other threads within tests
- but any such calls must be completed before the test completes - it’s an error to call a mock afterwards.
- You can use mocks within
Futures
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 object
s?
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.