It is a little hacky, but I think this is the simplest and clearer approach. Use this conditional compilation directive:
{$IfNDef TEST}
private
{$EndIf}
Your unit test project must define TEST in project → conditional defines
. Without a visibility specification, they become published.
Beware: if the private visibility isn't the first one in the class declaration, it will get the previous definition. A safer way, but more verbose and less clear, would be:
private
{$IfDef TEST}
public
{$EndIf}
This has a lot of advantages over the subclassing or other approaches:
- No extra complexity: no extra classes in your code.
- Nobody can "mistakenly" subclass and override your class: you preserve your architecture.
- When you say a method is protected, you somewhat expect that it will be overridden. You are telling this for who is reading your code. A protected method that shouldn't be overridden will confuse your code readers, breaking my first programming principle: "Code must be written to be read by other human beings."
- DUnit is in their own unit, not included everywhere.
- You don't touch messy RTTI.
I think it is a clearer solution, and better than the selected answer.
When I use this, I also configure the test project to put the build objects in a different directory of the main project. This prevents the binaries with the TEST directive to mix with the other code.