Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 33,179 of 33,346    |
|    Ulrich Eckhardt to All    |
|    Re: Is it a bad idea to define private:     |
|    30 Aug 13 00:59:25    |
   
   From: ulrich.eckhardt@dominolaser.com   
      
   Am 25.08.2013 14:43, schrieb DeMarcus:   
   > In books about TDD I've seen various solutions to do White-Box   
   > testing, i.e. test the protected and private parts of classes.   
   >   
   > I came up with an idea that if you do the following it would be easy   
   > to test the internal parts of a class.   
   >   
   > #define protected public   
   > #define private public   
      
   This is "opening" the class in order to allow unit testing. While this   
   C++ code is dangerous things like this work in general (as others have   
   elaborated). I'd suggest a different approach:   
      
      
   class my_module {   
    // validate class invariants   
    void validate() const;   
    struct invariant_guard: noncopyable   
    {   
    explicit invariant_guard(my_module const* m):   
    m_module(m)   
    {   
    assert(m_module);   
    m_module->validate();   
    }   
    ~invariant_guard()   
    {   
    assert(m_module);   
    m_module->validate();   
    }   
    private:   
    my_module const* m_module;   
    };   
   public:   
      
    void some_function()   
    {   
    invariant_guard guard(this);   
    ...code...   
    }   
   };   
      
      
   The idea is to use an RAII helper class to validate class invariants on   
   function entry and exit.   
      
      
   There are a few aspects to this that might be appealing:   
      
   1. When debugging, you will get a notification on exit of the function   
   that broke the deal. When unit testing, a violation of the internal   
   guarantees often causes a crash or a hanging unit test, which is why I   
   prefer this when running it in the IDE's debugger and not in some   
   nightly build.   
      
   2. The code is right at the programmer's fingertips. When someone   
   changes the class internals, they will also see this and adapt it   
   accordingly. Also, it is not some external tests, possibly written by   
   someone else, that defines how my own code must behave, but it is my own   
   choice to change and adjust things.   
      
   3. If you want, you can easily turn these (expensive) validations off in   
   a single place, maybe even via #ifdef NDEBUG. Or you can turn them on   
   even in optimized release builds for a single class.   
      
   4. Another variation of this is to throw an exception when the class is   
   invalid on function entry. You can't do that on exit because it might be   
   while stack unwinding due to an exception. This is a bit ugly, because   
   you keep an invalid object, but at least it can't be used any more since   
   the next entry will find the same state. In some cases where a clean   
   shutdown implies a DoS for other parts, this can be used. It's still   
   better not to write any bugs though. ;)   
      
      
   Another aspect is not as nice, that this doesn't lend itself to testing   
   behaviour. However, the only behaviour really relevant is the one that   
   is visible externally, and that should be verified with black-box unit   
   testing. I agree that it helps having some internal utilities tested   
   though and if it's just for easier diagnostic. Since those are internal,   
   too, point 2 above also applies and I sometimes trigger an ad-hoc test   
   function on startup for debug builds, but that's a different issue.   
      
      
   Happy hacking!   
      
   Uli   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca