Wednesday, August 12, 2009

Functional thinking, unit testing, and the hole in the middle II

Following on from this post...

Summer, the vacation season, and time when things need to get checked in to "shelf" status while the developer goes on leave, and I get a massive review and patching up of bleeding edges to do, the latest of which has been an interesting experience.

The code I was presented with is tidily written, well commented, and is what a few years ago I would have considered to be good code -- the dev who wrote it is a competent engineer, but just not close to the leading edge. So there was an apologetic note about not having been able to test a layer of the code directly above the database abstraction interface (beneath which code is all generated and subject to separate testing).

Showing how to inject a mock of the interface was easy -- but that alone would have left a mountain of unit tests to write for anything approaching good coverage. The problem was that a lot of code was repeating the same mantra

Is the record set empty?  If so return an empty array
Create a new typed collection
For each record
  create new typed object
  initialize a type specific list of properties from fields in the record
  add object to collection
Create a new typed array of sufficient size
Copy from collection to array
Return array

which is just crying out to be factored into the generic recipe as above, with the initialization line passed in as a lambda or delegate. And that factoring alone should give an order of magnitude reduction in the amount and complexity of unit tests required, which should result in a less traumatic item in the in-tray ready for the return from vacation.

Hopefully this will also be a dramatic enough object lesson in the sheer niftiness of the functional hole-in-the-middle pattern.

No comments :