Here's a video I made that captures my current thoughts on writing complex business rules which have lots of validation logic.
Here's the scenario I show in the video:
A Validate method on an object actually uses lots of smaller methods to return a result. The idea is to actually write separate tests for the underlying helper methods (which are actually individual rule checks) and a separate test for the overall logic driver (the Validate method.
Different from traditional TDD technique
This is different from the traditional way I would do TDD in that in the traditional sense, in TDD you probably would not have these helper methods but would actually write all that logic inside the validate method, and only later you would refactor the code into separate smaller methods.
- TDD: Start with a simple method and refactor it into smaller methods if and when you need to while making the tests pass.
- This method (Composite Logic TDD - CLTDD???): drive the creation of the separate rules as part of the TDD effort (part of the initial design).
But why? Because every time I tried to accomplish the same thing with the traditional way I came up with problems thinking about my next tests. every time I would add another rules to the implementation it would break my existing tests because they had to account for my new rule.
In the new method I gain full control over what the rules actually return so that I can tell the validate method - "Assume that all the rules pass, except this one". then I can go on and test things separately. here's what I mean:
So the video details how you would write all this in a test driven manner. I'm personally not entirely happy with it and i think the technique is still rough around the edges (takes time to learn, not very intuitive etc..) but it's currently the only way I could come up with to test the logical driven separately from the individual rules it uses.
Separation of concerns
The thing I like about the end result is that the individual rules methods (HasDIgit() etc..) can be coded and tested independently from the logic that uses them. much like separating a call to a web service from the actual web service implementation and testing them separately.
Your input is welcome. I'm looking for:
- Giving a proper name for this technique\pattern (the XUNit test patterns book calls the pattern "Test Specific Subclass" with the variation of "Behavior changing subclass" but what I'm doing is a pattern for TDD that tests a composite logic piece of code. what should we call this technique?
- Tell me where I'm missing something in the technique that could lead to potential problems
- tell me if you think you have a better way of accomplishing this (in TDD or not)
Here's the video, 44 minutes.(the demo of the validate method starts at minute 21)
in the video(you can also download it 57 MB):
- understanding the problem
- the different kinds of tests for this problem
- a simple demo of the extract and override pattern
- the full demo of using the Validate method
here are the slides for this video.