Saturday, March 03, 2007

Mocking with EasyMock

Until now I've been using JMock (currently 1.1) for creating mock objects in my unit tests. Yesterday a decided to give a try to EasyMock (currently 2.2) and ... I must say that I like it very much its approach and will continue to use it, probably switching from JMock (but this I can't say for sure at this point). So I will share some first thoughts about it.

What I liked more about EasyMock is the ease when creating mocks without much hassle. For example I had a test written in this way:

/**
* Check that proxy works when on-demand instantiation creates
* an object which implement the right interface.
*/
public void testProxyWorksOk() {
Mock mockCfgElement = mock( IConfigurationElement.class );

mockCfgElement.expects( once() )
.method( "createExecutableExtension" )
.with( eq( ExtensionsProxyFactory.CLASS_ATTR ) )
.will( returnValue( new ProxyWannabe() ) );

IProxyWannabe proxy = proxyFactory.getProxy(
IProxyWannabe.class,
(IConfigurationElement) mockCfgElement.proxy() );

assertEquals( 0, proxy.getDummy() );
proxy.costlyMethod1();
assertEquals( 1, proxy.getDummy() );
assertNotNull( proxy.costlyMethod2() );
}

This uses the typical JMock-pattern for writing expectations using some kind of specific API for testing (expects( once() ).method( "" ) ...). Typically what you would do is:
  1. Write the expectation(s) for your mock object (what methods are to be called, with which parameters and what values are to be returned).
  2. Get an object implementing the interface you want your object to be tested with.
  3. Run the method you want to test with this mock.
  4. Verify the expectations.
With JMock verification is automatically performed at the end of the method. But the biggest problem here is the passing of the expected method as a string: this is going to give some headache in case of refactoring (something that is going to happen often when acting in a test-driven way). Also the way of passing parameters seems a bit bloated ( with( eq( ... ) )... ).

The same test with EasyMock becomes:

public void testProxyWorksOk() throws Exception {
IConfigurationElement mockCfgElement = createMock( IConfigurationElement.class );

expect( mockCfgElement.createExecutableExtension( ExtensionsProxyFactory.CLASS_ATTR ) )
.andReturn( new ProxyWannabe() );
replay( mockCfgElement );

IProxyWannabe proxy = proxyFactory.getProxy( IProxyWannabe.class, mockCfgElement );

assertEquals( 0, proxy.getDummy() );
proxy.costlyMethod1();
assertEquals( 1, proxy.getDummy() );
assertNotNull( proxy.costlyMethod2() );

verify( mockCfgElement );
}

You will notice:
  • The mock factory method returns an interface compatible with the one we want to mock (IConfigurableElement, in this case): JMock creates a proxy object (instance of type Mock).
  • Writing the expectation is pretty straightforward (and less bloated).
  • Verification must be performed explicitely.
Additionally, you test-cases classes can only inherit from the usual JUnit's TestCase base class while with JMock you must inherit from MockObjectTestCase (not shown here). This is because EasyMock uses static imports from Java 5.0 (and so it can't be used with older JDKs ).

Some resources for the ones who have lived in Outer Space and don't know about mock objects:
Let's see how JMock2 will cope with the challenge ...

Thursday, March 01, 2007

Some OSGi links

Just some references to interesting links related to OSGi stuff.
Lastly but not least, I've found a parley from Ramnivas Laddad about DDD and AOP: really enjoyed it!

Monday, February 26, 2007

A new life for this blog

Yeah, this blog has been resurrected! I will use it mainly for posting interesting (I hope!) stuff about my research along the Collaborative Development Group where I'm attending my Ph. D. course.

For the people who doesn't know about: I'm back in Brindisi after my brief transfer in Rome (less than 6 months!) and now work for the United Nations International Computing Center (cool name, eh?).

The good:
  • I work at just 5(!) minutes from home!
  • It is a well paid job (much more than current italian salaries ...)
The bad:
  • It's a .NET-everywhere ecosystem
  • It will last until 20 July 2007 :|

Thursday, March 02, 2006

(Rail) road to Rome!



Finally it is time to leave (hmmm ... at 0625am tomorrow :O). See ya and hope the train will not feature the usual delay! (Murphy, please don't listen to this)

Sunday, February 26, 2006

Time for a new life!


Back to blogging! I'm now ready to leave for my new job in Rome. I'm going to work in Pro-netics, a software development firm heavily committed in Open Source: whatever it will end, I'm sure I'm going to learn a lot :)


Fortunately, Murphy is busy elsewhere: I've been able to get a room near work :D
More about this next time.

Saturday, June 18, 2005

Checkstyle & ant classpath ...

Just finished to fight against my ant build.xml and trying to make checkstyle-4.0.0-beta4 work ... This has been hard because of my inexperience when dealing with the tool's configuration: basically checkstyle doesn't work with my system antlr-2.7.5 :O and was continously throwing exceptions about a not found class:

...
[checkstyle] Running Checkstyle 4.0-beta4 on 9 files
[checkstyle] Can't find/access AST Node typecom.puppycrawl.tools.checkstyle.api.DetailAST
[checkstyle] Can't find/access AST Node typecom.puppycrawl.tools.checkstyle.api.DetailAST
[checkstyle] Can't find/access AST Node typecom.puppycrawl.tools.checkstyle.api.DetailAST
[checkstyle] Can't find/access AST Node typecom.puppycrawl.tools.checkstyle.api.DetailAST
...


Removing it from my ant classpath solved the problem (had to edit /usr/bin/ant:108 on my gentoo box). A few seconds fix after a whole day struggle ...

There is something wrong here ...