White box testing - friends or preprocessor?

Imagine we have a class:

class Testee { public: void Func() private: void auxFunc() }; 

and we want to conduct a block test on it on a white box. What do you think is the best approach? Declare the tester class as a friend of the test class? Or use a preprocessor as follows:

  class Testee { public: void Func() #ifndef UNITTEST_SYMBOL private: #elif public: #endif void auxFunc() }; 

and then in the test file

 #define UNITTEST_SYMBOL #include "Testee.h" #undef UNITTEST_SYMBOL 

So, again, what do you think is the best approach? Or maybe you could suggest a different approach.

+4
source share
4 answers

What about:

 #ifndef UNITTEST_SYMBOL #define semiprivate private #else #define semiprivate public #endif 

and declare your class as follows:

  class Testee  {  public:    void Func()  semiprivate:    void auxFunc()  }; 

or even if you hold on enough, #define private public when testing

+4
source

In the unit test file. You can try

 #define private public #include "Testee.h" 

This is what I am doing, it means that there is nothing related to unit testing in the header file. I find this very useful as it is hard for me to follow when there is a lot of #ifdef in my code.

Then I have all my header files before #define

+2
source

Using the friend method, the declaration will depend on the name of the test class, so if you ever change its name, the declaration must also be changed. In addition, I use Unittest ++, so the actual name of the test calss is formed by a macro.

Then the method with the definition is less hassle. Also, I would just put the definition as a global compiler option instead of the way you show, e.g.

 gcc -DUNIT_TESTING_ON #ifdef UNIT_TESTING_ON public: //or protected maybe #else private: #endif 

Anyone who reads this also sees what the purpose is, it is more clear than looking for a friend’s definition to understand why you made him a friend.

+1
source

Below is the way people follow to test the white box,

 #define private friend cTestDriver; private #define protected friend cTestDriver; protected //included all your class header from which you like to access //the private/protected method #include Testee.h" #undef private #undef protected 

The cTestDriver class will have shells / setters / getters to access all private and protected members.

You should also be aware of the order of the header files.

For instance:

File1.h

 #include "Testee.h" -- -- -- 

file TestDriver.h

 #include File1.h #define private friend cTestDriver; private #define protected friend cTestDriver; protected //included all your class header from which you like to access //the private/protected method #include Testee.h" #undef private #undef protected 

In the above case, Testee.h will be open while we open File1.h. So macros here will not be effective.

Note: you may receive a warning about multiple friend announcements.

0
source

All Articles