My lead is enforcing TDD on our project. He says he’s following Uncle Bob (Robert Martin) and SOLID principles. One of the rules he’s reinforcing is what I call “the single cog rule”–there should be no more than one cog in the implemented chain in your unit test.
We have a component that has a repository (IRepository) dependency. We’ve mocked the repository. The component that fetches from the repository passes a predicate to filter the list of items to be returned. My implementation had stub data get returned from a mock (Moq) repository and executed the predicate passed in from the component’s invocation to filter the stub data, and the test validated that the filter accomplished an obvious filtering requirement by stubbing an implementation on the mock repository and invoking the mock repository’s implementation. My lead clobbered this implementation and replaced it with an invocation of this:
protected static Expression<Func<T, bool>> RepositoryFilterVerification<T>(T entity)
{
return It.Is<Expression<Func<T, bool>>>(y => y.Compile().Invoke(entity));
}
His concern is that by executing the expression by stubbing the mock and invoking the mock the test is doing too much.
I was wondering what others felt about this.
EDIT: I had previously stated that he brought in a hundreds-lines-long ExpressionVisitor utility that validated that the expression explicitly matched an expression, but it turned out he wasn’t using it for this.
As you now describe it, I agree with your lead. What you need to test about your method is that it passes the correct predicate to the repository. What the repository does with the predicate belongs in a test of the repository unit.
1