A brief aside from all the techno-babble.
You know how when you’re on the other side of the world and you say where you’re from people always say things like, “Oh, my second cousin Jake lives there, you must know them…”
Well in the spirit of the aforementioned, and in the knowledge that there are quite a few java bloggers in Sydney: My sister (Anna Hobbs) lives there and some of her friends are developers. Anyone reading this know her?
JMock is your friend…
JMock does actually look quite similar to what I’ve done, but it is focussed more on the normal use of Mockobjects – ie. checking they were called with the expected values.
I’m not really doing Mocks at this point – its more like convincing an application that its running inside a real servlet container. Which means that I have to be able to understand that when I get a call like request.getHeader(“user-agent”), I need to return “Fakezilla”, but when I get request.getHeader(“if-modified-since”), I have to return a valid date string, or null. I’m not trying to assert how the mocks are called, just fake up a convincing looking environment. What I’ve ended up with is essentially a form of dynamic dispatch, as each mock has a collection of MethodReceivers in a Map keyed by method name, and each MethodReceiver has a Map of MethodReturn objects, keyed by an ArrayList of the arguments. Its then a case of calling getReturnValue on the MethodReturn object (confused yet?). I can therefore return different responses based on the actual values (not just type) of the arguments.
I can also simply make the Mock return a hard-coded response directly where I can get away with it (methods with no arguments for example).
There’s some syntactic ugliness in the setup code due to Java’s lack of enclosures – the closest approximation I’ve found is to implement an interface ‘in-place’ with an anonymous block. The alternative is hundreds of really tiny and very similar looking concrete classes.
The whole thing isn’t exactly generic or lightweight, as you have to know quite a lot about what your application is going to need in the way of parameters, and which methods its going to call on the request/response objects, but it has been quite illuminating finding out just how the application in question interacts with its environment.
And its nice to work on something a little off the wall every now and then 🙂
The Lucene guys have added an updated file format information page. Interesting for wannabe searchengine technology mavens (like me).
There’s also a new article on the site about the LARM webcrawler project that’s currently underway here.
Spent the afternoon making a servlet based application run all by itself by mocking the HttpServletRequest/Response, ServletContext etc etc. interfaces. It was also a great opportunity to use dynamic proxies in anger for the first time. I ended up with a rather nice abstract implementation of InvocationHandler that contained a Map of method names and MethodReceiver objects for the calls I cared about. Using dynamic proxies saved loads of time – I could code up canned responses to the method calls I was interested in and ignore the rest. It was kind of fun being able to instantiate a servlet inside a TestCase, call doGet() and get all the HTML dumped to System.out.
I didn’t quite reimplement EasyMock from scratch, but there’s probably some synergy to be had there…
I’ve posted a straight copy of my ANT build file for Webwork up here.
The project is just something I was toying with as an excuse for learning Webwork & Castor – its vapour at the moment – don’t expect a Roller-killer anytime soon 🙂
I’ll add some more details (source code, jsp’s, required jar files etc.) as and when it occurs to me.
Untangling the Gordian Knot. Currently working on a project to untangle a hairball project. Its quite tempting to cut the Gordian Knot, but we… [development]
Interfaces are my friend in this situation. I have found it really useful to extract a single method on the bloated object I’m trying to break up into an interface, and substituting a reference to the interface in the calling code wherever possible, repeating for each method, initially by defining one interface per method, and occasionally consolidating the interfaces where I find that several of them are passed around together. It does mean that for really blob-like objects, at about the halfway stage I find myself with humourous constructors like:-
MyThing thing = new MyThing(this, this, this, this, this);
Where ‘this’ is some bloated object that now implements 5 distinct interfaces, and the target class has been refactored to work through the interfaces. Its so obviously wrong that sheer embarrassment forces you to keep refactoring until its all clean. Writing tests gets really easy too. Its easy to make the TestCase implement an interface and pass itself to the object under test (self-shunt pattern) when the interface only declares one method!
Another useful AOP article here.