It came to my attention lately that you can unit test abstract base classes using Moq rather than creating a dummy class in test that implements the abstract base class. See How
You've already touched upon the "test the public API, not private" thought process, and you've also already mentioned the technique of inheriting from the class and then testing its protected members that way. Both of these are valid approaches.
Beneath it all, the simple truth is that you consider this implementation detail (as that's what a private or protected member is) important enough to test directly rather than indirectly via the public API that would use it. If it is this important, perhaps it's important enough to promote to its own class. (After all, if it's so important, perhaps it is a responsibility that MyAbstractClass
should not have.) The instance of the class would be protected inside MyAbstractClass
, so only the base and derived types would have access to the instance, but the class itself would be fully testable otherwise and usable elsewhere if that became a need.
abstract class MyAbstractClass
{
protected ImportantMethodDoer doer;
}
class ImportantMethodDoer
{
public void Do() { }
}
Otherwise, you're left* to the approaches you've already identified.
*Moq may or may not provide some mechanism for getting at private or protected members, I cannot say, as I do not use that particular tool. My answer is more from an architectural standpoint.