ryan norris managing software teams and delivering great results

16Apr/090

An Omniscient Learning Approach to Mock-based TDD

I recently posted about why I think mocks are simply the easiest way to get the most bang for your buck in automated software testing.  But integrating it as part of a process is hard, and teaching it is even harder.  Young developers seem to have a hard time grasping the idea of testing isolated units of code.  I'll confess - for a long time, much of my unit testing involved setting up the appropriate test environments - Spring containers for persistence units, test databases, you name it.  It's expensive to test this way, and there are only so many situations when integration tests are valuable.  On lean, agile teams - code coverage isn't held in as high regard as having working software.  On lean, agile teams - tests are a driver towards design, but they do need to be rooted in some level of initial thought on how a problem needs to be solved.

13Apr/090

Piling on Praise for Apache Wicket

I think someone finally got a web framework for Java right.

While I'm still yet to try on some of the AJAX support - something that makes or breaks a web framework these days - Wicket's clear separation of concerns and robust architecture for MVP (right, 'P', as in Model-View-Presenter) has really impressed me.  Generally speaking, I have not been one to embrace convention over configuration in frameworks like RoR, simply because it seems non-scalable.  But given it's pure focus on UI and it's total flexibility to do whatever the hell I want with my middle tier, I'm feeling that when restricted to the presentation layer - the paradigm works.  Wicket is pretty programmer-centric, so unlike RoR, you're not going to get off the ground without some skills or a scaffolding framework like Wicketopia, but I'm not at all convinced this isn't a bad thing.

There are a couple of things that I could get enthusiastic with around Wicket, were someone - including myself - to improve them.

  1. Documentation. Look, I hate documenting things as much as the next guy - but in as much as I've enjoyed the fruits of my labor in Wicket, I have not enjoyed chasing down information to all ends of the globe.  I love the fact that this is working software, and the curve isn't too steep - but try finding stuff on form validation, or the entire concept of mounting URL paths.
  2. Callbacks, anyone? So, forms in Wicket generally appear to be processed by the onSubmit() method of the Form class.  You override this in your child class of form.  This is the very object-oriented way of doing things, but it seems a touch limiting out of the box to not be able to register callbacks on this method.  My Form class exists so that I can have more than one of these per page, no doubt (take THAT ASP.NET), but I still think that I'd like to be able to actually register callback handlers as I wish in each Page, thus allowing Forms to have different behaviors dependent on where they are used.  I'm pretty sure this isn't the 80% use case, but I still am left with only one alternative out of the box, and that's to keep extending the class hierarchy.  It's nice to embrace strategy pattern and all, but to me this is where we really need an observer.

    So I was able to fudge this myself by creating a FormSubmitListener interface, subclass Form and implement it's onSubmit() to call the formSubmitted() method from my new interface, it's own implementation registered through the constructor on my Form subclass - but I think in an MVP or MVC framework, I still would like the ability to use OOP to handle the quirks of the page lifecycle (yeah, yeah - Wicket is unmanaged), but allow observers to actually handle pseudo-user events.

These two things aside, I feel pretty at peace with Wicket as my web framework for Java projects going forward (sorry Seam).

Another note - I'm really interested in the possibilities of packaging all of the resources for the web project in the JAR file.  While WAR's are fine for deployment, JAR's make the application open for truly modular design.

Now to refresh my memory on getting JTA running in a pure servlet container...

Tagged as: , No Comments
8Apr/091

Mocks – the only thing separating complex TDD from value-added TDD

About two years back when I started getting completely fascist about test-driven development, the complexity was always "gee, i have an application container and I need to involve it in my unit tests so that I can get full test coverage !!111oneeleventy."

This typically meant providing a real collaborator, like a PersistenceUnit in Java, so that I could test trivial operations like persisting an entity.  At the time, I challenged a manager on this:

What are we really testing?  Are we testing OUR requirement, or are we testing something we should reasonably expect Hibernate to do on the basis of our initial technology selection?

Code coverage I believe is pretty overrated.  No one cares whether or not you can prove your method to persist an entity works because the developers of Hibernate/TopLink/LINQ to SQL have already proved this through their unit tests. What you are building when you write a test that actually checks the database to see if your middleware used a pre-packaged object-relational manpping framework correctly is an integration test.  There's certainly value to integration testing with data access layers, particularly when difficult to test components of your middleware (like stored procedures and triggers) are involved.  Saving that however, the focus of test-driven development - namely unit tests, should be on the business logic that is proprietary to your applicatiom, be it the front-end or the middle tier.

Now, suffice to say that to a good number of developers and architects this isn't news, but if you really want to isolate the code which you wrote that is specific to your business rules and requirements - mocking frameworks are the way to go.  Particularly in an Agile project where we can readily identify certain injected dependencies (like an EntityManager, for example) as a collaborator of the class under test, your unit test is really interested in asking the question based on this interaction with this external component, how should I expect my logic to react?

In these scenarios of course, I mock or stub the EntityManager.  In the past, a fool like me would have tried to load a container within my unit test environment.  This is actually an integration test, in addition to the fact that it is costly and doesn't add the value a truly isolated unit test which focuses on the code you wrote does.

In .Net, RhinoMocks is scalding hot with it's supprt for mocking through lambda's.  In JEE, I've fallen in love with Mockito.

So, stop worrying about how you can get JBoss running so that your CI environment can execute inside of it.  Instead, use mocks to give your code the resources it needs to vet out the conditions in your own code that you want to test.

8Apr/092

Diving back into Java, and liking it (mostly)

So for various reasons, I've pulled Eclipse Ganymede down and decided to check in on where Java has gone during my year-long mental hiatus in Redmond.  I have certain biases now from the land of .Net, and god help the Java world if it angers me after seeing the things I've seen in the last year.

All in all, I'm very pleased.

The m2eclipse plugin is marvelous, finally.

The day has finally come where I'm no longer fighting Eclipse to build projects using Maven, as it should be.  Maven ties far too many niceties of the world together, and to not have it as the underlying, portable build tool within the IDE has always frustrated me.  The ability to quickly start a new Maven project, apply an archetype and go is fantastic.  The fact that it doesn't require special jazz to get a WTP project up and running is even better.

Hey look, working with my database and some JPA implementation is really easy!

...well, almost easy.  I created a project for my middleware just using the quickstart archetype.  I was just going to throw Spring on top of it and avoid spoiling the good experience so far with EJB insanity.  The next thing I wanted to do was load up my database tables as ORM classes via Hibernate.

For whatever reason, this was cool on my Mac.  Project Properties...JPA Tools...Generate entities.  This is somehow not the way to do it over in windows.  So instead I tried to add JPA as a project facet.

My first problem was that I didn't have Hibernate set up as my default JPA provider.  Unfortunately, you can only do this through the Maven-managed dependencies.  It has to be an Eclipse user library.  So I download the Entity Manager and wire it up into Eclipse.  Add the Java Facet (somehow not a default, probably Maven's fault), added the JPA Facet (and am told I need to add the Utility Facet, so I do that).

Further configuration required.

Ok.  So I click into this further configuration and it reasonably wants to know how I connect to the database.  Fair enough.  I do all this, and it still won't let me apply the change.

Eventually, it appears you need to add the Java project facet first, and then and only then can I reopen the properties page and apply the JPA facet.  A frustration point, but I figured it out.

Hey, nothing special to get a project with the Wicket archetype running in WTP.

I start a separate web project and use the Wicket archetype, interested in tackling what looks to be a nice, lightweight UI package for Java (though it looks like Spring integration isn't trivial - which is basically unacceptable these days).  I start the project, I add a server configuration, and deploy...

Holy crap, it works out of the box!

I have a ways to go, but things feel more turnkey with Eclipse than I've ever experienced.  I did up some JUnits with Mockito, and that was easy, indicating that if I were to set up Cruise or some other CI tool, I could quickly get going with a full Agile project.  Exciting stuff.