• Home
  • Events
  • About
  • Spock and Test Spies: A Logical Choice

    Here at Canoo many of us are preparing to spend the next three days in the Alps at a bi-annual retreat called “Code Camp”, where we stay up all night hacking with technologies and on projects that don’t always fit within our normal projects. This is my first time going, but I hear from the old timers that it is three days of a Spartan like existence focused on replacing sleep with marathon coding sessions, and where anyone causing a build failure is kicked into the Well of Souls with a scream of “FOR SPARTA!”. I am… nervous.

    Those who know me should not be surprised at my technology stack: Groovy for the language, Gradle for the build, and Spock for the unit tests. In preparation for the big event, I dropped Spock into our project, converted all the unit tests to Spock specifications, and then converted all the hand rolled mocks to Spock Interactions. (Why these aren’t called “Spock Mocks” or simply “Smocks” I do not know).

    First Reactions
    First, the Spock framework does some crazy language tricks that aren’t supported in Java or Groovy… and it does so in a statically typed way. Almost all my mocking code has the same IDE completion and navigation the Java solutions have. Pretty amazing stuff given the level of metaprogramming that is going on in the implementation. Optional static typing in Groovy is a very important feature, especially for tool support.

    Secondly, did you know the JVM supports long, punctuated, multi-line method names? Check out this example:

    These long method names are a feature of Spock, not Groovy. Some features of Groovy will not work if you try this in GroovyTestCase, such as using closures. Let’s move on to the mocking and spying code.

    Spying
    I wrote a post many moons ago about the difference between stubs, spies, and mocks. Spying on indirect output of a test is much more important to me than full blown mocking, and I feel extensive mocking is a design smell. So far, I’ve been impressed with the Spock’s ability to analyze test objects after the fact to determine what was and was not called on them. For instance, here is a simple Spock spec asserting that the mouseClicked was indeed called once:

    Mocks are created with the Mock() method in the setup: phase, the system is tested in the when: phase, and the system is verified in the then: phase. Anything in then: is considered an assertion.

    The assertion line reads in English, “expect one time that mouseClicked was invoked”. If mouseClicked is not called by the test then the test fails. If mouseClicked is called more then once then the test failes. If it is called with the wrong parameter… yes, it fails. Any number is supported, not just one, and ranges are supported as well in the same syntax:

    The range (2.._) means 2 to anything, or at least 2 times. (_..3) means from anything to 3, or at most 3 times. The little _ is the wildcard. But what is it doing as a method parameter? I’ll explain that in one second… first check out how regular expressions can be used to specify interactions:

    This says, “make sure neither mousePressed nor mouseReleased were invoked in this specification. Your excitement for this feature will depend on your excitement for Regexs in general.

    Method Constraints
    Spock reinvents Matchers, doing away with the verbose syntax. The previous examples used equality in the matches:

    This is going to perform an equals() comparison on the argument to make sure it matches exactly. You also briefly saw the _ constraint, meaning match anything at all no matter what:

    And there is also the wildcard with type constraint, which will match anything with the specified class:

    You can even get fancy with custom constraints, where you can easily specify in a closure the details of your match. That sure beats implementing IArgumentMatcher!

    Negatives work as well, such as “not null” or “not an instance”:

    There are a lot of options, and there are no subclasses or interfaces to implement. Everything is a one liner without a lot of DSL daisy chaining of method calls. I like it, and I’m excited to use it heavily up at camp next week.

    Target Constraints
    Matchers, or constraints, aren’t just for parameters in Spock. I have never seen this before, but you can add an expectation on the left hand side of mocks, not just the right hand side. In effect, there is a way to say, “expect that method X was invoked on any of my mock objects in scope, I don’t care which one”. In this example, there are 2 mouse listeners in scope, and mouseClicked is randomly invoked on only one of them. The assertion makes sure that at least one was invoked:

    Admittedly, I do not have a real use for this today. But it is unique, I have never seen it before.

    Failures Accumulate

    One last point to mention… failures in expectations accumulate. No exception is thrown until the end of the method, at which point all failures are reported in a batch. For instance, assume that the following expectations are run, and all of them fail:

    The resulting error message reports all failures, not just the first one:

    Great stuff. You can try out Spock in the SpockConsole, and you can see some photos from out last Code Camp on Flickr. And watch this space for future posts after we are all finished. Thanks!

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • DZone
    • Y!GG
    • Webnews
    • Digg
    • del.icio.us
    • DotNetKicks
    • Facebook
    • Google Bookmarks
    • Newsrider
    • Twitter
    • YahooBuzz

    2 Comments »

    1. Ravi Hasija said,

      July 30, 2010 @ 21:33

      Cannot read the block that is supposed to show actual code. Please verify this. I checked on IE and Opera.

    2. Hamlet said,

      August 12, 2010 @ 12:22

      sorry, there was an issue with wordpess. is fixed now.

    RSS feed for comments on this post · TrackBack URI

    Leave a Comment


    nine + = 12