We have recently adopted the specification patterns for validating domain objects and now want to introduce unit testing of our domain objects to improve code quality.
One problem I have found is how best to unit test the validate functionality shown in the example below. The specification hits the database so I want to be able to mock it but as it is instantiated in-line I can’t do this. I could work off interfaces but this increases the complexity of the code and as we may have a lot of specifications we will ultimately have a lot of interfaces (remember we are introducing unit testing and don’t want to give anyone an excuse to shoot it down).
Given this scenario how would we best solve the problem of unit testing the specification pattern in our domain objects?
...
public void Validate()
{
if(DuplicateUsername())
{ throw new ValidationException(); }
}
public bool DuplicateUsername()
{
var spec = new DuplicateUsernameSpecification();
return spec.IsSatisfiedBy(this);
}
A more gentle introduction of Seams into the application could be achieved by making core methods
virtual. This means that you would be able to use the Extract and Override technique for unit testing.In greenfield development I find this technique suboptimal because there are better alternatives available, but it’s a good way to retrofit testability to already existing code.
As an example, you write that your Specification hits the database. Within that implementaiton, you could extract that part of the specification to a Factory Method that you can then override in your unit tests.
In general, the book Working Effectively with Legacy Code provides much valuable guidance on how to make code testable.