How to unit test C++ private and protected member functions?

In the unit testing world, sometimes we encounter a situation where we need to unit test private or protected member functions. There is a lot of arguments surrounding this topic. Some claim that if a private member function needs testing, it implies that there is a need for refactoring. However, I strongly feel that protected member functions are still APIs and people often are in a situation where they need to unit test some of them. One of the simple ways that I found was to declare the test suite class to be the friend of that is to be tested. It is better to scope the declaration in an #ifdef block.

class Foo {
  public:
#ifdef UNITTEST
    friend class FooTest;
#endif
    ...
 
  protected:
    ...
 
  private:
    ...
};

It would be even better to come up with an helper macro like the following.

#ifdef UNITTEST
#define ASSIST_UNIT_TEST( class__ ) friend class class__##Test
#else
#define ASSIST_UNIT_TEST( class__ )
#endif

And use the above macro in the class to be tested.

class Foo {
  public:
    ASSIST_UNIT_TEST( Foo );
    ...
 
  protected:
    ...
 
  private:
    ...
};

We can have the macro UNITTEST to define only for the unit test code. During this exercise, I found that I dearly missed __CLASS__ macro in C++ badly! I documented this approach in the cppunit FAQ page.

I have also tried to create a wrapper class that derives from the class to be tested and override the protected functions so that they are in the public scope of the derived class. This can help testing only protected member functions. However there is a lot of new code involved in the wrapper class to invoke the base class’ appropriate function. So, I consider this ineffective and error prone.

PS: If someone knows a better approach to do this in C++ please let me know.

  • Digg
  • del.icio.us
  • Twitter
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • Live
  • Yahoo! Bookmarks
  • Posterous
  • Sphinn
  • Mixx
  1. Class A
    {
    friend class A_test;
    private:
    int i;
    void foo( void );
    };

    class A_test : public A
    {
    public:
    // this will work in C++0x
    // using A::A

    using A::i;
    using A:foo;
    };

    A_test test;
    test.i = 10;

    This has minimal code in the wrapper class. In fact the function addresses are the same between A and A_test. The major short comming is the lack of forwarding constructors. That will be fixed in c++0x, until then I build several wrapper constructors, one for each possible way to construct A, e.g. if A has a constructor with a default param, A_test has two constructors.

  2. In your unit test C++ file, do the following:

    #define private public
    #include “Foo.h”

    Now your unit test can access all of Foo’s private member functions.

    Drew

  3. To Drew,
    If you compile the code to test (such as Foo.cpp, etc) into a library, there are linker errors sometimes, because the symbols exported are different between public and private.

    Beyonddoor

  4. I have add the code

    #define private public

    before class, but I have got linker error:

    error Link2022: metadata operation failed (80131195) : Custem attributes are not consistent: (0x0c000628)

    So, cow can I solve this problem ???? what should I do ????

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">