I’ve just released ScalaMock 2.1, with the following improvements over 2.0:
- Add support for polymorphic (type parameterised) methods
- Add support for curried methods
- Fix String constants in Java classes
- Fix unmocked operators
ScalaMock is a native Scala mocking framework which, as well as traits (interfaces) and functions, can also mock:
- Classes
- Singleton and companion objects (static methods)
- Object creation (constructor invocation)
- Polymorphic (type parameterised) methods
- Classes with private constructors
- Final classes and classes with final methods
- Operators (methods with symbolic names)
- Overloaded methods
ScalaMock (previously Borachio) is a mocking library for Scala. As well as traits (interfaces) and functions, it can also mock:
- Classes
- Singleton and companion objects (static methods)
- Object creation (constructor invocation)
- Classes with private constructors
- Final classes and classes with final methods
- Operators (methods with symbolic names)
- Overloaded methods
This post describes how to setup a project that uses ScalaMock in conjunction with ScalaTest and sbt 0.11. The sample code described in this article is available on GitHub.
Note: If you only want to mock functions and traits (interfaces), you can use ScalaMock’s proxy mocks by simply linking with the .jar file – no need to use the compiler plugin or sbt plugin described below.
The example assumes that we’re writing code to control a mechanical turtle, similar to that used by Logo programs. Mocking is useful in this kind of situation because we might want to create tests that function even if we don’t have the hardware to hand, which run more quickly than would be the case if we ran on real hardware, and where we can use mocks to simulate errors or other situations difficult to reproduce on demand.
Getting started
- Create a root directory for your project:
- ScalaMock uses a compiler plugin to generate code. There’s an sbt plugin that makes setting this up easy. Add this plugin to your project by creating
project/project/Build.scala containing:
import sbt._
object PluginDef extends Build {
override lazy val projects = Seq(root)
lazy val root = Project("plugins", file(".")) dependsOn(scalamockPlugin)
lazy val scalamockPlugin = uri("git://github.com/paulbutcher/scalamock-sbt-plugin")
}
- Create
project/Build.scala containing:
import sbt._
import Keys._
import ScalaMockPlugin._
object MyBuild extends Build {
override lazy val settings = super.settings ++ Seq(
organization := "com.example",
version := "1.0",
scalaVersion := "2.9.1",
resolvers += ScalaToolsSnapshots,
libraryDependencies += "org.scalamock" %% "scalamock-scalatest-support" % "2.0-SNAPSHOT",
autoCompilerPlugins := true,
addCompilerPlugin("org.scalamock" %% "scalamock-compiler-plugin" % "2.0-SNAPSHOT"))
lazy val myproject = Project("MyProject", file(".")) settings(generateMocksSettings: _*) configs(Mock)
}
Simple mocking
- Now we’ve got a project, we need some code to test. Let’s start with a simple trait representing a turtle. Create
src/main/scala/Turtle.scala containing:
package com.example
trait Turtle {
def penDown()
def penUp()
def forward(distance: Double)
def turn(angle: Double)
def getPosition: (Double, Double)
def getAngle: Double
}
- The turtle API is not very convenient, we have no way to move to a specific position, instead we need to work out how to get from where we are now to where we want to get by calculating angles and distances. Here’s some code that draws a line from a specific point to another by doing exactly that.
Create src/main/scala/Controller.scala containing:
package com.example
import scala.math.{atan2, sqrt}
class Controller(turtle: Turtle) {
def drawLine(start: (Double, Double), end: (Double, Double)) {
moveTo(start)
val initialAngle = turtle.getAngle
val deltaPos = delta(start, end)
turtle.turn(angle(deltaPos) - initialAngle)
turtle.penDown
turtle.forward(distance(deltaPos))
}
def delta(pos1: (Double, Double), pos2: (Double, Double)) =
(pos2._1 - pos1._1, pos2._2 - pos1._2)
def distance(delta: (Double, Double)) =
sqrt(delta._1 * delta._1 + delta._2 * delta._2)
def angle(delta: (Double, Double)) =
atan2(delta._2, delta._1)
def moveTo(pos: (Double, Double)) {
val initialPos = turtle.getPosition
val initialAngle = turtle.getAngle
val deltaPos = delta(initialPos, pos)
turtle.penUp
turtle.turn(angle(deltaPos) - initialAngle)
turtle.forward(distance(deltaPos))
}
}
- In order to create mock turtles, we need to tell ScalaMock to generate the appropriate code by using the
@mock annotation. Create src/generate-mocks/scala/GenerateMocks.scala containing:
package com.example
import org.scalamock.annotation.mock
@mock[Turtle]
class Dummy
- We can now write a test. We’ll create a mock turtle that pretends to start at the origin (0, 0) and verifies that if we draw a line from (1, 1) to (2, 1) it performs the correct sequence of turns and movements.

Create src/test/scala/ControllerTest.scala containing:
package com.example
import org.scalatest.FunSuite
import org.scalamock.scalatest.MockFactory
import org.scalamock.generated.GeneratedMockFactory
import scala.math.{Pi, sqrt}
class ControllerTest extends FunSuite with MockFactory with GeneratedMockFactory {
test("draw line") {
val mockTurtle = mock[Turtle]
val controller = new Controller(mockTurtle)
inSequence {
inAnyOrder {
mockTurtle.expects.penUp
mockTurtle.expects.getPosition returning (0.0, 0.0)
mockTurtle.expects.getAngle returning 0.0
}
mockTurtle.expects.turn(~(Pi / 4))
mockTurtle.expects.forward(~sqrt(2.0))
mockTurtle.expects.getAngle returning Pi / 4
mockTurtle.expects.turn(~(-Pi / 4))
mockTurtle.expects.penDown
mockTurtle.expects.forward(1.0)
}
controller.drawLine((1.0, 1.0), (2.0, 1.0))
}
}
This should (hopefully!) be self-explanatory, with one possible exception. The tilde (~) operator represents an epsilon match, useful for taking account of rounding errors when dealing with floating-point values.
- Generate mocks with
generate-mocks and then run the tests with test:
$ sbt
> generate-mocks
[log generatemocks] Creating mock for: trait Turtle
> test
[info] ControllerTest:
[info] - draw line
[info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0
Getting clever: Constructors and singleton objects
- Turtles use ink. Let’s define a singleton object that keeps track of how much we’ve used.
Create src/main/scala/InkReservoir.scala containing:
package com.example
object InkReservoir {
def use(r: Double, g: Double, b: Double) {
red -= r
green -= g
blue -= b
}
private var red = 10.0
private var green = 10.0
private var blue = 10.0
}
- And now let’s create a concrete implementation of our
Turtle trait, which adds the ability to define a pen colour, together with a factory method implemented in its companion object.
Create src/main/scala/ColouredTurtle.scala containing:
package com.example
import scala.math.{cos, sin}
class ColouredTurtle(r: Double, g: Double, b: Double) extends Turtle {
def penDown() { penIsDown = true }
def penUp() { penIsDown = false }
def turn(angle: Double) { theta += angle}
def getPosition: (Double, Double) = (x, y)
def getAngle: Double = theta
def forward(d: Double) {
x += sin(theta) * d
y += cos(theta) * d
if (penIsDown)
InkReservoir.use(r * d, g * d, b * d)
}
private var penIsDown = false
private var x = 0.0
private var y = 0.0
private var theta = 0.0
}
object ColouredTurtle {
def apply(colour: Symbol) = {
val (r, g, b) = colourMap(colour)
new ColouredTurtle(r, g, b)
}
private val colourMap = Map('red -> (1.0, 0.0, 0.0), 'green -> (0.0, 1.0, 0.0), 'blue -> (0.0, 0.0, 1.0))
}
- To mock
ColouredTurtle, first we need to add another @mock annotation to GenerateMocks.scala:
- We can now write a test to verify that our factory method works.
Create src/test/scala/ColouredTurtleTest.scala:
package com.example
import org.scalatest.FunSuite
import org.scalamock.scalatest.MockFactory
import org.scalamock.generated.GeneratedMockFactory
class ColouredTurtleTest extends FunSuite with MockFactory with GeneratedMockFactory {
test("coloured turtles") {
val m1 = mock[ColouredTurtle]
val m2 = mock[ColouredTurtle]
m1.expects.newInstance(1.0, 0.0, 0.0)
m2.expects.newInstance(0.0, 1.0, 0.0)
m2.expects.forward(3.0)
val t1 = ColouredTurtle('red)
val t2 = ColouredTurtle('green)
t2.forward(3.0)
}
}
- Run the tests again (don’t forget to run
generate-mocks first) to see:
[info] ColouredTurtleTest:
[info] - coloured turtles
[info] ControllerTest:
[info] - draw line
[info] Passed: : Total 2, Failed 0, Errors 0, Passed 2, Skipped 0
- Finally, we can add a test to verify that we’re keeping track of ink correctly. Let ScalaMock know that we’ll be mocking
InkReservoir by adding a @mockObject annotation:
@mockObject(InkReservoir)
And add a test to ColouredTurtleTest.scala:
test("ink reservoir") {
val m = mockObject(InkReservoir)
m.expects.use(0.0, 3.0, 0.0)
val t = ColouredTurtle('green)
t.penDown
t.forward(3.0)
}
[info] ControllerTest:
[info] - draw line
[info] ColouredTurtleTest:
[info] - coloured turtles
[info] - ink reservoir
[info] Passed: : Total 3, Failed 0, Errors 0, Passed 3, Skipped 0