
On Thu, Dec 22, 2011 at 8:59 AM, Chris Cleeland
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
wrote: 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.
In your header (the class to be tested, you need to forward declare the test namespace and the tester class, e.g. // ClassToBeTested.h // You may be able to generate the forward declaration using a script and put it in an include file that you // include here. namespace test { class TesterOfClassToBeTested; } namespace myOtherNamespace { // optional class ClassToBeTested { friend class test::TesterOfClassToBeTested; // here's the one line :) public: private: }; } // TesterOfClassToBeTested.cpp #include "ClassToBeTested.h" #define foreach BOOST_FOREACH using namespace std; using namespace boost; using namespace stage; namespace test { class TesterOfClassToBeTested { public: TesterOfClassToBeTested() { } void copy_constructor() { ClassToBeTested loc2; ClassToBeTested loc(loc2); BOOST_REQUIRE(loc.locIdStruct == loc2.locIdStruct); } ~TesterOfClassToBeTested() { } private: }; } BOOST_AUTO_TEST_SUITE(TesterOfClassToBeTested) struct fixture { test::TesterOfClassToBeTested t; }; BOOST_FIXTURE_TEST_CASE(copy_constructor, fixture) { t.copy_constructor(); } BOOST_AUTO_TEST_SUITE_END()
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 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users