
Thanks to all for the suggestions! You are correct that I'm testing
"legacy" code, though in this particular case the legacy code is
completely open for change. But, I need unit tests before I go
mucking about so I know that I haven't made things any worse than they
are.
On Wed, Dec 21, 2011 at 7:04 PM, Ahmed Badran
That is what I've come to accept as probably the cleanest possible solution without hacking/redefining "private"/"protected" in production vs. test code (even though it's far from what I would call elegant). For a class I essentially create a friend in a completely different "test" namespace, the unit tests go in that namespace and are linked against the object files to test them and validate class internals/invariants. The shipping code (headers) always have the 'missing' friend declarations, but as I said it's a 1 line that I've gotten to accept as the least ugly solution until I come across something that's more elegant.
For some reason I'm having difficulties implementing this suggestion. The "legacy" code lives in a namespace, e.g., // ClassToBeTested.hh namespace mycompany { namespace internal { class ClassToBeTested { ... }; } // namespace internal } // namespace mycompany If I understand the suggestion, I think I want to put the testing in a different namespace, e.g., // test_ClassToBeTested.cxx namespace mycompany { namespace internal { namespace test { // here lies the boost unit test stuff that I create struct ClassToBeTested_suite_fixture { ... }; BOOST_FIXTURE_TEST_SUITE( ClassToBeTested_suite, ClassToBeTested_suite_fixture ) ... here lie unit tests... BOOST_AUTO_TEST_SUITE_END() } } } So, in the declaration for ClassToBeTested, I should have something like class ClassToBeTested { public: // public interface protected: // protected members/methods friend class mycompany::internal::test::ClassToBeTested_suite_fixture; }; When I compile, the compiler complains that it does not know about namespace 'test' ]$ clang++ namespace_test.cxx namespace_test.cxx:4:46: error: no member named 'test' in namespace 'mycompany::internal' friend class ::mycompany::internal::test::ClassToBeTested_suite_fixture; ~~~~~~~~~~~~~~~~~~~~~~~^ namespace_test.cxx:6:8: error: expected external declaration } } } ^ 2 errors generated. The only way I've found around this is to forward declare ClassToBeTested_suite_fixture in the ClassToBeTested header, e.g., // ClassToBeTested.hh namespace mycompany { namespace internal { namespace test { class ClassToBeTested_suite_fixture; } class ClassToBeTested { ... }; } // namespace internal } // namespace mycompany Is this the technique that you use? I wonder, because it's more than one lane and still intrusive, and I'm wondering if I'm missing something. -- Chris Cleeland