Tuesday, 6 January 2009

Mock external components using AOP

Mark Nadelson has provided a well-written tutorial for a novel (to me, at any rate) use of Aspect-Oriented Programming in Java. Read the "print" version to get the whole article in one lump without the commercials.

When you write jUnit tests, you often encounter a need to create mock objects (e.g. using JMock or EasyMock) that can simulate some external dependency of the software under test. Mark has extended this idea to any external component that has an interface. In order to determine whether the software under test uses a mock component or the real one, he uses dynamic aspect-weaving by means of Spring AOP with AspectJ annotations.

I've got to have a play with this approach to see whether it can be used flexibly enough to support TDD fully. One problem I could foresee is that the pointcut specification is not in the test script but in the mock object (i.e. the class that implements the aspect). So it might be less than straightforward to link the mock object to specific test cases/steps. By contrast, when you use JMock in a jUnit test, you specify both the mock object and its expectations in one place.

3 comments:

Jonas Bandi said...

Hi Immo,

the article is quite a concise short introduction into AOP.

But I am not sure if the proposed solution is actually the right way to go ...

As I gather it two problems are addressed:
1. Mocking of classes instead of interfaces
2. Mocking without controlling the instantiation of the mocked object.

The first concern is no issue any more today:
EasyMock offers EasyMock Class Extension, jMock offers ClassImposteriser and Mockito offers mocking classes out of the box...

With these tools together with a sensible IoC/DI-Design (which addresses issue 2) you can easily reach a good testability in my opinion.

If you want to address also the second issue, JMockit is an option.

If you think about it the underlying solution is the same/very similar to using an AOP library -> some bytecode manipulation by libraries like CGLIB, javassist, ASM ...

But I think it is easier to learn/integrate a mocking framework than a generic AOP framework ...

Links:
EasyMock class extension

jMock ClassImposteriser

Mockito

JMockit

By the way - here is a nice blog post about the evolution of mocking-frameworks by Jay Fields

Immo Hüneke said...

Thanks Jonas - I knew about ClassImposteriser (have used it to good effect on several occasions), but not the others. I'll try to read the Jay Fields article when I get time.

Immo Hüneke said...

I have now read Jay Fields's article and it certainly made me think again about unit test and mocking syntax. In particular, Jay's approach to unifying the syntax for expressing the expected results of a test looks very promising - see his Ruby framework expectations. Incidentally, I like the way the Rubyforge site sets out the code! Very reminescent of the good old Smalltalk code browser.