home bbs files messages ]

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 32,785 of 33,346   
   =?UTF-8?Q?Tobias=20M=C3=BCller?= to Ian Collins   
   Re: Unit Testing Frameworks (was Re: Sin   
   09 Jan 13 15:57:42   
   
   l-september.org> 10cf4d62   
   From: troplin@bluewin.ch   
      
   Ian Collins  wrote:   
   > Tobias Müller wrote:   
   >>   
   >> Öö Tiib  wrote:   
   >>> It has been several times asked in this thread: Why it is difficult to   
   >>> create fake Singleton::instance() that is instrumented to return an   
   >>> mock object that you want? Usual answer has been repeated "clear and   
   >>> obvious" fact that DI is somehow simpler. Ok, but why and how?   
   >>   
   >> Usually, you test the external interface of a class if it behaves the way   
   >> it has to. The use of a singleton in the class is an implementation detail   
   >> and may thus easily be forgotten to test.   
   >   
   > How can you test the behaviour of a class without testing how it   
   > interacts its environment?  You most certainly can't if you develop test   
   > first.   
      
   That's the point exactly. With DI you make clear which parts of the   
   environment you are actually using.   
      
   >> With DI, you the "singleton" is part of the public interface of the class   
   >> and can be tested without making assumptions on the internals of the class.   
   >   
   > The internals of which class?   
      
   The one under test.   
      
   > If you are testing how the class under   
   > test uses the singleton, the internals of the real singleton are   
   > irrelevant.   
      
   Yes of course.   
      
   > Your task is to check whether (and how) the appropriate   
   > member functions are called and the behaviour of your code to given   
   > return values.   
      
   Same question, do you mean the members of the class under test or the   
   singleton?   
      
   If you mean the singleton, then I disagree. It's rarely specified that a   
   class must call some specific singleton methods in a specific way.   
      
   For example you have a configuration singleton. All classes in your project   
   can use it if they want. But they don't have to. It's up to the implementor   
   of the class. In the best case it is specified documented if the class uses   
   the configuration. In the worst case the documentation is wrong or   
   outdated. If it's not documented you have to guess or look at the code.   
      
   > To do this, you either have to jump through hoops of   
   > fire to instrument the real code, or use a mock.   
      
   Same for DI, but it's much easier to substitute the real code with the mock   
   when using DI.   
      
   >> With DI you have to specify an interface for those "singletons" that may be   
   >> injected, with a real singleton one is tempted to just create, use and   
   >> modify it ad hoc. A well defined interface is always good for testing.   
   >   
   > Eh?  A singleton is no different from any other class form a testing   
   > perspective.   
      
   A singleton is often designed with the assumption that there's only one   
   class/instance anyway, so one tends to be a bit sloppier. Need a new   
   method? Just add one, not much to think about.   
   With DI this is different. You rely on polymorphism (compile time via   
   templates or runtime via interfaces). There you cannot just change   
   something without breaking code.   
      
   >> Of course you can replace a singleton with a mock if you really want to.   
   >> But you cannot just take you library and build a test application around   
   >> it. You have to exclude the complete singleton implementation from the   
   >> original code and replace it with a different one.   
   >   
   > Isn't that what mocking is all about?  At least in my world everything   
   > that isn't part of the unit under test is mocked. That's why we have   
   > mocking frameworks to do the donkey work for us.   
      
   The difference is, that with DI the real code can still be around, just not   
   used. With a singleton however, only one can exist at a time.   
      
   >> In practice that means you have to replace some source files with others   
   >> just for testing. You cannot use the original binary to build your tests   
   >> around it, but have to compile (at least link) everything again. Possibly   
   >> even with different compiler settings.   
   >   
   > The compiler settings are irrelevant.   
      
   I meant that the settings can be different by accident. So you are not   
   testing the same thing.   
      
   Tobi   
      
      
   --   
         [ 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