ScalaMock 3.0 Preview Release

Update: ScalaMock 3.0-M4 for Scala 2.10.0-RC1 is now released.

The current version of ScalaMock makes use of a compiler plugin to generate typesafe mock objects. This works, but has a number of problems, not least of which is the complicated nature of the build system required (meaning that it currently only works with sbt). The recent preview release of Scala 2.10 has opened up a new approach via its support for macros.

I’ve just released a preview of ScalaMock 3.0, a “from the ground up” rewrite using macros. It’s not yet as capable as ScalaMock 2.x (it can only mock traits – there’s no support for mocking classes, singleton/companion objects or object creation yet) but it’s certainly complete enough to be useful, I hope.

One significant (and frequently requested!) enhancement over ScalaMock 2.x is support for Mockito-style “record then verify” mocking as well as the more traditional “setup expectations” style.

The source is available on GitHub, and a snapshot release (Scala 2.10.0-M3 only) is available on Sonatype:

libraryDependencies +=
  "org.scalamock" %% "scalamock-scalatest-support" % "3.0-SNAPSHOT"

You can see examples of it in use in GitHub.

Here’s an example of a test written using the “setup expectations” style:

class ControllerTest extends FunSuite with MockFactory {

  test("draw line") {
    val mockTurtle = mock[Turtle]
    val controller = new Controller(mockTurtle)

    inSequence {
      inAnyOrder {
        (mockTurtle.penUp _) expects ()
        (mockTurtle.getPosition _) expects () returning (0.0, 0.0)
        (mockTurtle.getAngle _) expects () returning 0.0
      }
      (mockTurtle.turn _) expects ~(Pi / 4)
      (mockTurtle.forward _) expects ~sqrt(2.0)
      (mockTurtle.getAngle _) expects () returning Pi / 4
      (mockTurtle.turn _) expects ~(-Pi / 4)
      (mockTurtle.penDown _) expects ()
      (mockTurtle.forward _) expects 1.0
    }

    controller.drawLine((1.0, 1.0), (2.0, 1.0))
  }
}

and here’s the same example rewritten to use the Mockito-style record and then verify approach:

class ControllerTest extends FunSuite with MockFactory {
  import scala.language.postfixOps

  test("draw line") {
    val mockTurtle = stub[Turtle]
    val controller = new Controller(mockTurtle)

    inSequence {
      inAnyOrder {
        (mockTurtle.getPosition _) when () returns (0.0, 0.0)
        (mockTurtle.getAngle _) when () returns 0.0 once
      }
      (mockTurtle.getAngle _) when () returns Pi / 4
    }

    controller.drawLine((1.0, 1.0), (2.0, 1.0))

    inSequence {
      (mockTurtle.turn _) verify ~(Pi / 4)
      (mockTurtle.forward _) verify ~sqrt(2.0)
      (mockTurtle.turn _) verify ~(-Pi / 4)
      (mockTurtle.penDown _) verify ()
      (mockTurtle.forward _) verify 1.0
    }
  }
}

Right now, it supports:

  • Mock functions (including higher-order functions)
  • Polymorphic traits
  • Polymorphic methods
  • Curried methods
  • Overloaded methods

Here’s my todo list:

  • Sort out the documentation
  • Take advantage of macro types (type providers) when available in a subsequent Scala release. This will enable a slightly nicer syntax for method mocking:

    mockObject.expects.method(arguments)

    instead of:

    (mockObject.method _) expects (arguments)

  • Mocking classes (as well as traits)
  • Mocking singleton/companion objects
  • Mocking object creation

I’d be very grateful for any feedback, in particular bug reports.

3 Responses to “ScalaMock 3.0 Preview Release”


  1. 1 Fernando Racca June 4, 2012 at 2:02 pm

    Looks great, in particular “mockObject.expects.method(arguments)”

    Unfortunately I’m not using 2.10-M3 yet, but this is a great incentive to start using it :)

    Cheers!

  2. 2 vips June 5, 2012 at 5:21 am

    Hi Paul,
    What is the advantage of scalamock over mockito?

    • 3 paul June 5, 2012 at 1:45 pm

      The primary benefit is that it’s written for Scala, so it understands various Scala-only things like first-class functions, curried methods, by-name parameters, singleton/companion objects, etc. (note that this is not yet entirely true of the preview version of ScalaMock3 – although it will be when I’m finished with it). ScalaTest and Specs2 both have Mockito wrappers which go some way towards persuading Mockito to work well with Scala, but it’s unfair to expect a framework written for Java to fully understand Scala.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





Follow

Get every new post delivered to your Inbox.

Join 242 other followers

%d bloggers like this: