When using the decorator pattern it is a common practice to create a base class implementation of the abstraction that simply forwards all calls to the decorated class. This means that in the actual functional decorators, once you derive from this base class, you only need to implement the behaviour for the specific methods of interest rather than every method. The caveat though is that, because C# methods are not virtual by default you must remember to mark all methods as virtual.
I used to think it gave little benefit to write unit tests for these base decorators but a couple of experiences have shown that without too much effort you can write tests that live as guards as the decorated abstraction evolves. The two main issues I have seen are:
- Failing to forward on the call to the downstream object
- Failing to mark the base implementation as virtual
To solve issue 1 we just make sure we have tests that cover each of the methods on the abstraction. As an example, take an abstraction for a prioritised queue:
Now we can write tests for a decorator base class quite easily to verify forwarding:
However, how do we write a test to ensure all members are virtual? Well, reflection to the rescue. We can look at each method in the SUT and verify it is virtual. However, beware that the MethodBase class has an IsVirtual method but this does not mean the same as the keyword in C#. Interface implementations also return IsVirtual as true as they are also subject to virtual dispatch. What we really are looking for is a way to ask "is this method overridable?". To ensure that we also need to check that the IsFinal flag on MethodBase is false.
Now we are much more likely to catch issues with the base class as the abstraction evolves.