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,786 of 33,346   
   =?ISO-8859-1?Q?=D6=F6_Tiib?= to Richard   
   Re: Unit Testing Frameworks (was Re: Sin   
   09 Jan 13 15:58:25   
   
   From: ootiib@hot.ee   
      
   On Wednesday, 9 January 2013 04:20:01 UTC+2, Richard  wrote:   
   > =?ISO-8859-1?Q?=D6=F6_Tiib?=  spake the secret code   
   > <36be4d19-4c67-49e2-9385-43502c25fbef@googlegroups.com> thusly:   
   > >On Monday, 7 January 2013 21:29:59 UTC+2, Richard  wrote:   
   > >> Ian Collins  spake the secret code   
   > >> >You appear to have missed the point that you don't use the real   
   > >> >singletons in unit testing, you use mocks.   
   > >>   
   > >> I don't disagree with that approach, but when I have code that is   
   > >> directly coupled to Singleton::instance(), how do you slip the mock   
   > >> in for testing?   
   > >   
   > >With a mock Singleton::instance() function that returns mock   
   > >Singleton?   
   >   
   > So you're proposing link-time substitution of mock implementations.   
   > While this is certainly feasible, it is less than desirable, because   
   > it means that noone else in my unit test executable can call the real   
   > function, only the mock.   
      
   Yes, I think that most C++ unit tests use the preprocessor and the   
   linker to create and prepare mocks for the testable unit. If something   
   is internal part of testable unit then it should not be altered to not   
   enforce internal design with tests. If it is outside of testable unit   
   then it has to be replaced to achieve specific test situations.   
      
   What are the alternatives? To instrument executable code run-time? It   
   is possible, but it is far more complex than with some script language   
   or compiled language that contains reflection. Design specially for   
   run-time  instrumentation? Majority of C++ source code on planet Earth   
   is not but needs to be tested too.   
      
   > >> The easiest method is to use DI on the SUT so that it gets an   
   > >> instance of the collaborator from it's c'tor instead of through a   
   > >> global static method.   
   > >   
   > >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?   
   >   
   > If the return type of Singleton::instance() isn't an interface, I have   
   > to not only supply a link-time substitution for this static method,   
   > but also for whatever it returns, which may mean lots of boiler plate   
   > that I have to provide by link-time substitution.   
      
   That is usually exactly what one wants to do in unit test. Lets take few   
   examples. The external object (singleton or not) that testable unit uses   
   is:   
   a) "Database". No one wants to use a real SQL database in unit test.   
   Typically some fake (one that works like real but is in memory) database   
   is used and filled with test situation data prior to test.   
      
   b) "GUI View". Who wants real GUI in unit test? It is typically some   
   mock (one that fakes user input) GUI there.   
      
   c) "Logger". Issues with logs are rare so most tests just want a dummy   
   (that does nothing on logging requests) logger.   
      
   Yes, that all means special source code that tests. Dummies (that do   
   nothing) are small and reusable. Fakes (that fake the real thing) are   
   sometimes big but also reusable. Mocks are usually generated by   
   framework. Preparing mocks and fakes and verifying the results are   
   part of test itself and syntax of it is usually unified by framework.   
      
   > Basically, while link-time substitution is a mocking method that works   
   > in C++, it is less desirable than interface polymorphism because it   
   > brings along with it extra baggage and constraints.   
      
   It is done and used for years. It can *surely* bring difficulties that   
   we haven't met in situations that we haven't been in but just saying   
   "it brings" is not convincing without being more specific.   
      
   Example: Testable unit calls 2 external functions (not part of the unit)   
   during its work. These 2 functions have to be replaced with fake, mock   
   or dummy functions. How else?   
      
   The code of testable unit looks different (and may easier or harder to   
   read or to maintain) depending if these functions are virtual member   
   functions, non-virtual member functions, free functions or pointers   
   to any of those. From testing perspective these are just functions that   
   are not part of testable unit.   
      
   There is technical difference if replaced by preprocessor, by linker or   
   run-time somehow but replacement code that takes place of the functions   
   in test has to be somewhere.   
      
      
   --   
         [ 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