Pros
- You can access the private members to test them
- Its a fairly minimal amount of
hack
Cons
- Broken encapsulation
- Broken encapsulation that is more complicated and just as brittle as
friend
- Mixing test with production code by putting
test_backdoor
on the production side
- Maintance problem ( just like friending the the test code, you've created an extremely tight coupling with your test code )
All of the Pros/Cons aside, I think you are best off making some architectural changes that allow better testing of whatever complex stuff is happening.
Possible Solutions
- Use the Pimpl idiom, put the
complex
code in the pimpl along with the private member, and write a test for the Pimpl. The Pimpl can be forward declared as a public member, allowing external instantiation in the unit test. The Pimpl can consist of only public members, making it easier to test
- Disadvantage: Lots of code
- Disadvantage: opaque type that can be more difficult to see inside of when debugging
- Just test the public/protected interface of the class. Test the contract that your interface lays out.
- Disadvantage: unit tests are difficult/impossible to write in an isolated manner.
- Similar to the Pimpl solutions, but create a free function with the
complex
code in it. Put the declaration in a private header ( not part of the libraries public interface ), and test it.
- Break encapsulation via friend a test method/fixture
- Possible variation on this: declare
friend struct test_context;
, put your test code inside of methods in the implementation of struct test_context
. This way you don't have to friend each test case, method, or fixture. This should reduce the likelyhood of someone breaking the friending.
- Break encapsulation via template specialization