Coming from an Enterprise Java background to the world of Force.com development, two things I have found myself missing most of all (putting to one side the lack of a debugger!) are a good mocking framework and built-in support for dependency injection.
Anyone familiar with the practice of Behaviour Driven Development and wanting to practice this when writing Apex code has no doubt found themselves missing exactly the same things.
So I decided to see what would be possible on the Force.com platform, given the limitations of Apex.
(For those interested in the DI aspects of all of this, Jesse Altman, Force.com MVP, has done some great work in this area http://jessealtman.com/2014/03/dependency-injection-in-apex/)
Why Behaviour Driven Development?
Test Driven Development as a practice has been around for a good while now. It seems to be one of those things which divides opinion quite strongly! Personally I have found it to be a really great way to help me design code which attempts to adhere to SOLID principles. Applying TDD in this way puts the focus very clearly on the driven aspect of TDD, using tests to help drive the design of the system. And the key thing we want to design is the behaviour of the system, which leads nicely onto BDD. BDD re-emphasises the behavioural aspect of TDD, in that any tests we do write should be testing behaviour and never implementation.
Two Approaches to Unit Testing
My thinking in this area is heavily influenced by GOOS as it is affectionately known by its fans. In very simplistic terms, if we view any system as being comprised of components which send messages to each other to achieve the behaviour of the system, one of the key things we will want to design and test are the components and the messages they send to each other. This approach to TDD is known as ‘Mockist’ as opposed to what is sometimes called a ‘Classicist’ approach, which puts the emphasis on asserting the state of the system rather than behavioural interactions. (This is not without controversy itself. Anyone who has read Mocks Aren’t Stubs by Martin Fowler will know what I mean, his article is very much worth reading if you’ve not done so already. One of the authors of GOOS replied to this here State vs Interaction Based Testing.)
I think in reality both approaches – mockist and classicist – are valid and the key thing is knowing how and when to apply which one, and that only comes with experience.
Mock objects really help an outside-in approach to BDD – most of the time I find myself using a mocking approach to discover interfaces for classes that don’t yet exist. The mock objects I use whilst applying BDD at one layer of the system help me to discover the responsibilities of the next layer in.
One of the objections to this approach you might here is something along the lines of ‘but I really want to design by contract and design all my interface definitions upfront’. Using this approach does not mean you haven’t thought through the high level architectural design of the system, but it can really help clarify your thinking at the detailed component level. (Uncle Bob posted an interesting discussion on this recently)
Guiding design is one of the (main?) reasons to use a mocking framework, so I am going to assume you’ve done your own thinking about this and would like to try that out on the Force.com platform.