Thursday, June 10, 2010

Loving Spock Framework

I have been following the progress of the Spock Framework for sometime and today decided to take the plunge.

As a JUnit user and having used mocking frameworks like EasyMock and Mockito, I set to work trying to convert a test I had written earlier.

One of the things I found hard to get past was the need to inherit from a given class, namely the Specification. Once I had looked around the code and found that it was built to work in that way, I got down to it. I like the way in which tests are expressed.

I found the interactions/mocking slightly different, especially the syntax. I like the way in which you can use wild card matchers for parameters and number of calls but returning values from a mocked object's interactions was less than intuitive.

Where in the EasyMock world you would say something like


expect(mockedObject.calledMethod()).andReturn(value);


In Spock it would look something like the following


mockedObject.calledMethod() >> {value}


I am hoping that at some point there might be a different way to express that expectation as it currently looks a bit cryptic.

All in all I like that beyond your feature/test name you can self document tests to the extent that it becomes readable for non developers, so a heavy plus there. I also like the fact that IntelliJ and Maven all understand and can run Spock Specifications without any trouble.

In the coming days I will be using the Spock Framework a bit more, especially as I would love to discover other features like Unroll. Will let you know how I get on.

Peace and Love.

3 comments:

Peter Niederwieser said...

Actually, the standard way to return a value is:

mockedObject.calledMethod() >> value

The arrows point "outwards" because the method "produces" a value.

If you need to return different values on successive calls:

mockedObject.calledMethod() >>> [value1, value2, value3] // or anything else Groovy can iterate over

The closure-based result providers are the most powerful ones. They are the equivalent to EasyMock's ".andAnswer(new IAnswer() { ... })". A few things you can do with them:

mockedObject.calledMethod(_,_) >> { int x, int y -> x * y }

mockedObject.calledMethod() >> { throw new Exception() }

mockedObject.calledMethod(_) >> { assert it[0] > 5 }

Cheers,
Peter

Peter Niederwieser said...

You may also be interested in What's new in Spock 0.4? Episode 2: Better mocking.

LHFVille said...

Thanks for the feedback Peter. Have read the article and will keep pressing ahead with Spock.