23 January 2007

Cutting back the noise

Recently I've been working with our experimental syntax for jMock2. We've added support for using the signature of the expected method by doing some pretty evil things with initialisation blocks. It's changing, but for today an expectation for a type
 public interface BlogWriter
    public List blogEntriesFor(Date date);
    public Reference updateBlogEntry(Blog blog, Entry entry) 
looks like this
 expects(new InAnyOrder() {{
    allowing(mockBlogWriter).blogEntriesFor(aDate); will(returnValue(aListOfEntries)); 
    one(mockBlogWriter).updateBlogEntry(aBlog, anEntry); will(returnValue(aReference)); 
  }})
The details of how this works are left as an exercise for the reader, but it means that the test is expecting one call to updateBlogEntry with the given arguments and that we've stubbed blogEntriesFor to return a list of entries. Using the original signature (as users of easymock have been telling us for ages) is really convenient when working with a refactoring IDE. Rename the method and the tests will change too. But I miss the brevity we could achieve with our old jMock approach. If I have a method I want to stub, I just want it to return a value whenever it's called, I could write
 expects(new InAnyOrder() {{
    allowing(mockBlogWriter).updateBlogEntry(aBlog, anEntry); will(returnValue(aReference)); 
  }})
This will only respond if the arguments equal the objects aBlog and anEntry, which is too restrictive. More important, it's misleading because those arguments are not important in this particular test. I just want the value returned so I can get to the interesting stuff later in the test, but I haven't clearly expressed that. I can relax the constraints on the stub (as best as we can manage within the Java type system)
 expects(new InAnyOrder() {{
    allowing(mockBlogWriter).updateBlogEntry(with(anything()), with(anything()); 
      will(returnValue(aReference)); 
  }})
This is not bad, considering, but still rather noisy for a supporting line of code. I'm emotionally attached to the terseness of
allowing(mockBlogWriter).method("updateBlogEntry"); will(returnValue(aReference));
(which is the jMock2 version of our jMock1 syntax). This says just what I need and no more.

No comments: