EasyMock. I prefer the new DSL-like approach.
Sadly, instead of creating a new package for the incompatible API (
easymock2 perhaps?), they prefixed incompatible interface names with an "I" and mixed old and new classes in the same package. Ewww.
But if you can look past the class evolution faux pas (the ugliness doesn't really impose itself on your code afterall), EasyMock has embraced JDK 1.5 generics to take static type checking for mocks to a whole new level.
First, creating a mock. They got it half right:
static <T> T createMock(Class<T> toMock)That removes the need to cast in simple cases, but, thanks to erasure, breaks for more complex cases (
T = List<String>for example). I think they really want:
static <T> T createMock(Class<? super T> toMock)EasyMock has always had good type checking when it comes to specifying what methods you expect your code to invoke. As before, you create a mock, invoke methods you expect your code to invoke with expected parameters, swich over to replay mode, and run your test code:
Foo mockFoo = createMock(Foo.class); mockFoo.doSomething(); replay(mockFoo); // code you expect to invoke doSomething(). verify(mock);Going in today, foremost on my mind was how would I tell EasyMock what to return from
Foo.doSomething()? To my pleasant surprise, not only can you specify a return value, but the code is statically typed! Say for a moment that
int. We can instruct EasyMock to return
Foo mockFoo = createMock(Foo.class); expect(mockFoo.doSomething()).andReturn(5); replay(mockFoo); // code which expects doSomething() to return 5. verify(mock);
To our benefit, the compiler verifies that that the types returned from
doSomething() and passed to
Before JDK 1.5 and generics came along, I said that no mocking framework was compelling enough for me to abandon plain Java mocking. EasyMock came close even then, but now it looks like I'll really have to change my tune. I'll test drive EasyMock in some real world tests and get back to you.