
Paul Giaccone wrote:
Ryo IGARASHI wrote:
On 3/23/06, Leif Gruenwoldt
wrote: Is there a way to test the private functions of a class without moving them into public scope during test?
What are some strategies for this?
Try following evil hack.
// someclass_test.hpp #define private public #define protected public
#include
#undef protected #undef private
Evil, evil, evil!
Slightly less so is what I have done in my code. Define a variable (say, TESTING) in the makefile or preprocessor definitions of your test program. In your class definitin, change "private:" to the following:
#ifdef TESTING public: #else private: #endif
Of course, you leave TESTING undefined (or make sure it is undefined) in your non-test program.
It's perhaps not nice to look at, but it's less nasty than the above hack, IMO.
Paul
Hi Paul, I wanted to add to your post. I am trying to figure out a good solution to Leif's problem for my own project. Your solution seemed good, but I also want the ability to test just the public interface, without simultaneous access to the private data. When I use the #ifdef TESTING solution, my unit tests never test the classes as they will be used by an end user because all class data is always public. This could lead to a false sense of security from my unit tests. So, here is my addition that I think is more comprehensive. - Separate tests of protected and private members into their own suites. - Surround these suites with: #ifdef TEST_PRIVATE BOOST_AUTO_TEST_SUITE( A_Private ); BOOST_AUTO_TEST_CASE( A_Test1_Private ) { A *p = new A(); BOOST_CHECK( p->privateData == 42 ); } BOOST_AUTO_TEST_CASE( A_Test2_Private ) { A *p = new A(); BOOST_CHECK( p->privateFunction() == "foo" ); } BOOST_AUTO_TEST_SUITE_END(); #endif //TEST_PRIVATE By switching the TEST_PRIVATE definition on or off, I can test either the pure public interface, or the private members temporarily exposed to public. I should probably also surround my public interface tests with: #ifndef TEST_PRIVATE Public Tests... #endif So, that I never accidentally mix the two groups, which would lead to a weakened set of tests on my public interface. You could also extend this to Protected members as well. #ifdef TEST_PROTECTED protected Tests... #endif //TEST_PROTECTED #ifndef TEST_PRIVATE || TEST_PROTECTED Public Tests... #endif //TEST_PRIVATE || TEST_PROTECTED You may want to keep protected tests separate from private tests as well. (and vice versa) #ifdef TEST_PROTECTED #ifndef TEST_PRIVATE protected Tests... #endif //!TEST_PRIVATE #endif //TEST_PROTECTED Any thoughts on this strategy? One potential problem I see is that all private data in every class in the testee app becomes public to each test at the same time. This strategy doesn't let you access private data one class at a time in your tests. Thanks, Ed