Sometimes the code we need to write is so simple that we cannot imagine getting it wrong. Going test-first in these cases just seems apt to lead to tedium and tautologies. This could be a fair point if the sole purpose of unit testing were bug-finding. But there is so much more to it than that as Jay Bazuzi points out in his “Why We Test” series. A test can be equally good as a safety net and an executable spec.
So how do we skip the drudgery but keep the value? One powerful technique is described by the Testcase Superclass pattern. Basically you write the boring stuff once, in essence “generalizing the specification.” Then you write just enough test code to wire up your domain object to this canned test suite.
On the web you can find a few examples of this approach applied to value objects: Kenneth Xu’s “Unit Test Value Object – Reusable Test Fixture” and Jared Parsons’ “Making Equality Testing Simple”.
With a bit of effort and some extension methods you can even shoot for Fluent Assertions-style readability:
[TestMethod] public void ShouldHaveValueEqualitySemantics() { ValueObject.OfType<MyObj>().WithExamples(() => new MyObj(1), () => new MyObj(2)).ShouldHaveValueEqualitySemantics(); }
(Implementation left as an exercise to the reader.) 😀
Now go ahead and destroy those bland and repetitive unit tests without fear of future fallout.