Menu

how best test protected member functions?

Help
Anonymous
2002-12-06
2003-03-01
  • Anonymous

    Anonymous - 2002-12-06

    I often find that I would like to test a class at a finer grain than its public interface.  Currently, I am using preprocessor directives in the class to be tested:

    #ifdef TEST
    public:
    #else
    protected:
    #endif

    I don't want to make the protected interface public just so that my test code runs, but I don't know a good way to use 'friend' to solve this problem and the directives sure make the class code ugly.  Maybe a slick macro, but I would rather not have to touch the class code at all.

    Does anyone have any thoughts on this?

    Thanks in advance,

    Jeremy

     
    • coinoperated

      coinoperated - 2002-12-06

      We use a similar technique but use an alias defined in a standard types header:

      #ifdef _DEBUG
      # define Testable public  // opened for testing
      #else
      # define Testable // closed for release
      #endif

      In the code :
      #include "OurStdTypes.h"
      class ToTest
      {
      public:
         // public interface
      private:
         // always private
      Testable:
        // open for testing only
      }

      Haven't found a less intrusive mechanism but would love to see one..

       
    • coinoperated

      coinoperated - 2002-12-06

      We use a similar technique but use an alias defined in a standard types header:

      #ifdef _DEBUG
      # define Testable public  // opened for testing
      #else
      # define Testable // closed for release
      #endif

      In the code :
      #include "OurStdTypes.h"
      class ToTest
      {
      public:
         // public interface
      private:
         // always private
      Testable:
        // open for testing only
      }

      Haven't found a less intrusive mechanism but would love to see one..

       
    • Tom Plunket

      Tom Plunket - 2002-12-06

      Wow, that's something.  :)

      My feeling is that if the tests are meant to be intrusive, make them intrusive.

      class MyClass
      {
         friend class MyClassTest

      // stuff
      };

      class MyClassTest : public CppUnit::Test { };

      AFAIAC, this class isn't meant for testing the interface of the class only.  Sometimes you may wish to test just the interface, but I prefer testing each of the member functions with an intrusive mechanism like friendship.  This has the benefit of also not using any preprocessor ugliness.

       
    • Wolfgang Stoecher

      When posting this question to an XP-forum, one of the answers was like this:
      "If you want to test a private method, then your class probably has aspects that can be taken out and separated into a new class."
      I take the need for testing a private/protected member as a "code smell". Refactoring always solved this problem for me and also resulted in a nicer structure.

      Wolfgang

       
    • Anonymous

      Anonymous - 2002-12-09

      First of all, thanks for the feedback.  Unfortunately, I am still searching...

      The 'Testable' alias is similar to, but cleaner than what I have been using.  My only gripe would be the name choice; it suggests that the public interface is not testable.

      The friend solution is what I first considered, but I would like to avoid dependencies of system code on testing code.

      I very much like the 'code smell' solution, but I'm not sure how to refactor my code as it is already quite reduced.  I have a public 'Step(...)' function that is called each "step" which, in turn, calls a list of protected functions (that may very between steps).  I could make all of the functions public to the client, but this would complicate thier code and I see no good reason to expose the protected interface.

      Thanks again for the input.  I will meditate on this :)

      Jeremy

       
    • Wolfgang Stoecher

      Hi Jeremy,

      from your short description I would guess that you have a state-machine and the states in one class?(or is it: container and iterator?)
      Do you know the state-machine-compiler (SMC) project at sourceforge? (smc.sourceforge.net)

      Wolfgang

       
    • Christian Furst

      Christian Furst - 2003-02-26

      The suggestion from Tom Plunket look nice but how do I accomplish it with CppUnit.

      My test class is declare like:
        template<typename T> class TestCMyClass(T t);

      I tried something like this:
      class CMyClass
      {
        #ifdef _TESTCASECODE
          template<typename T> friend class TestCMyClass(T t);
        #endif

       
      • Tom Plunket

        Tom Plunket - 2003-03-01

        using _TESTCASECODE as an identifier is a violation of the rules of the C++ language.  For more information on this and how to make template classes friends (I don't know how to do that off hand), ask on comp.lang.c++.

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.