I started asking myself some new questions today. I’m going to try to capture the thought process that led me to it here, so bear with me. I’ll get to the point eventually.
In response to a question today, I said that once someone has truly embraced unit testing on a decent sized project, they’d be forced to either re-invent mock objects if they hadn’t been exposed to the concept, or give up unit testing as too difficult. I’ve found myself using mock objects regularly in my unit tests. On the first project I used unit tests, I’d independantly decided to use lightweight inner classes within my test classes for the collaborators of the test class. I’m enough of a researcher that I soon learned and read about mock objects. I’ve heard similar stories from others. The point being that mock objects are a natural consequence of TDD (Test Driven Development) or even unit testing after writing the subject code.
The reason mock objects are a natural consequence is that using unit testing as a design tool leads us to loosely coupled code, just to make unit testing bearable. This has led me to rely less on static methods including the Singleton pattern. To make up for this, I find myself using JNDI and JMX more, as they provide a way to find collaborators without being tightly coupled. I’ve even written trivial partial implementations of each for use during unit testing. For actual deployment I’ve been using JBoss lately.
This week I’ve written a small system using JMX, MessageDrivenBeans, and utility classes stored in the JNDI tree. Each component has a good suite of unit tests and I have high confidence in the actual code. However, the next step of assembling these components into a useful application has been troublesome.
It was a good thing I was already writing a JMX MBean, because that’s apparently the only way to bind objects into the JNDI tree. Then it seems that the objects bound must be Serializable, even in the ‘java’ context. Then there were deployment order issues about whether I had to manually create an application specific sub-context, or whether the DataSource config file ran first and created the sub-context for me. Then I had to make sure I had all the JNDI mappings correct. The MessageDrivenBean looks up simple names, that are in a context specific to the bean, and the deployment descriptor maps those to where the real object is bound — this causes more order dependencies.
Now to my question. Is this really making our lives any simpler as developers? Are we truly raising the bar? I feel that I’m having to learn an additional programming language that is a mixture of Java, XML, properties, and general app server understanding in order to assemble my components. I’m worried that even though unit tests gave me confidence in each component in isolation, I have little confidence is the entire application assembly process.
The J2EE docs speak of those different roles of bean developer, deployer, assembler, administrator, etc. but in practice I’ve never seen those roles taken by different people. The developers are called upon to do them all. I’ve wondered for a while whether software development would reach the point where there’s a distinction between developers that write components, and people (developers, technical business analysts, users) who wire the components together into applications. Is the widespread use of unit testing going to bring us closer to this? And then the biggie: is it a desirable outcome?