Groovy Mocks

| | bookmark | email
Groovy supports "natively" mocks and stubs. I will not go into this topic as it is quite well covered here. However, basically what you can do is:
mock.demand.real_method(params) { params ->  /* the invocation params are passed to the closure */
    /* some code that will be executed when method is called */ 
}
mock.use {
  /* code that uses the mock */
} 

Exactly the same can be done with stubs. Groovy in Action explains the conceptual difference between mocks and stubs:
Stubs enable your CUT [n.b. class under test] to run in isolation and allow you to make assertions about state changes of the CUT. With mocks, the test focus moves to the interplay of the CUT and its collaborators. What gets asserted is whether the CUT follows a specified protocol.
There are other behavioral differences between mocks and stubs, so I would encourage you to get a copy of GinA for more details. The advantages and ease of usage are evident. As for TDD adepts I think they already know that using a dynlang will ease their life.
Another very cool feature of Groovy is the possibility to define properties. So, instead of having to write a java bean like:
class JavaBean {
  private String name;

   public String getName() { return name; }

   public void setName(String n) { name = n; }
}
you just need to write:
class GroovyBean {
  String name;
  // Well... this is all !
}
By this time you are already wondering what is the reason for this post and what is the link between Groovy properties and mocking (beside maybe advertising the coolness of Groovy mocks). Well, if you would be using Groovy mocks for a while you would have noticed that you cannot actually mock the property access (there was an workaround: explicit use of the getter, but this would have defended the whole idea around properties, didn't it?). So, fresh on the Groovy trunk there is support for mocking property access:
class Caller {
  def printTwo = { new Collaborator().one }
}
def mock = new MockFor(Collaborator)

mock.demand.getOne { "two" }
mock.use {
   def c = new Caller()
   assert    c.printTwo() == "two"
}
Considering that I got started on mocks, my next post will be about JMock2 and the (many) things I don't like about it.

Update: it looks like there is still one limitation for Groovy mocks/stubs: they cannot be used yet for constructors (GROOVY-1823). Code like this will not run:
def dateStub = new StubFor( Date )
dateStub.demand.Date{ aControlCurrentTime } // this syntax is however ugly