TestingPrivateMethodsInCeePlusPlus is a FAQ (Frequently Asked Question).
Quick Answer Think carefully before using private stuff in the tests. If you must, either make the test class a friend (using a forward class declaration), or put the code that must test private stuff in a public member of the class, e.g.
void class_under_test_c::test(void) {}What follows is a discussion extracted from CppUnit.
(1) Should Private Stuff Be Tested?
This viewpoint is represented by JohnGardner:
If a forward declaration is used, the testee does not depend on the tester.
(3) Provide public accessors for everything you want to test
But that's exposing private information to the whole world.
(4) Use a pre-processor macro PRIVATE instead of private:
#ifdef TEST_MODE #define PRIVATE public #else #define PRIVATE private #endifNow you can compile the program without TEST_MODE just to make sure that no access to private stuff is made by the program itself, and then compile with CppUnit with TEST_MODE defined and gain access to everything (this is probably the worst).
(5) #define private public This is sort of like option 4 of redefining private to be public with two big differences : You don't have to use ugly PRIVATE macro all over your code, but you have to #define/#undef the 'private' symbol before/after #including files to be tested. Since you develop tests incrementally it doesn't seem like a big burden.
#define private public // make sure we have access to private parts #include "class_under_test.hh" #undef private // restore privacy to private CPPUNIT_TEST_SUITE_REGISTRATION(CDomDocumentTest); ...According to the C++ standard, this may result in undefined behaviour, because it creates two different definitions of the same class in different translation units. Therefore you can only use this technique with a compiler that guarantees that it works, and not in portable code. -- NatPryce
AndyGlew comment: I think the undefinedness only applies if the two translation units are linked. If you recompile and link everything with private ifdeffed out, it should work, and vice versa. It's only if the definition is inconsistent that it causes a problem. Nevertheless, it's a dangerous practice.
(6) #define private protected Another way to deal with private members is to replace private with
#ifdef TESTMODE protected: #else private: #endifwherever it occurs. Or, equivalently, #define private protected
Then have the tester inherit the testee, this way private member are never turned into public ones and the tester don't have to be declared within the testee, it also makes the setup and clean up easier since the testee is initialized when the tester is initialized
Use Protected, not private
Yet another possibility is to not use private at all, but only to use protected. However, many folks, including BjarneStroustrup, find that protected inheritance is a dangerous thing to have period, and should be avoided.
Use Class Test Methods
Instead of trying to put the test in a separate class, create one or more test methods in the class under test. It is probably a flaw of C++ that all such methods / member functions have access to all private stuff, but they do.