l-september.org> 73ec3a48   
   From: pasa@lib.hu   
      
   On 1/8/2013 7:25 PM, 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.   
   > 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.   
      
   That sounds like a very good argument *against* DI.   
      
   You stated that use of the singleton was a detail of implementation   
   only. After the refactoring (hm, doe that still count as refactoring?)   
   you have it in the public interface. Where it should not appear if we   
   map the abstract design correctly.   
      
   For many singletons we deliberately don't test state, they are only   
   needed to allow the tested stuff work. For those actually involved with   
   testing mus have required change attached. What is hard to forget due to   
   that requirement being present. IMO it's a pretty lousy idea to mess up   
   an interface out of fear that someone forgets to read reqs doing   
   implementation, review and other testing. There must be better tools   
   present.   
      
   > 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.   
      
   I'd be interested in criteria for 'well designed' interface here. As   
   implementation-only stuff leaking to public portion for me indicates bad   
   one. And for general testability we already concluded that there's no   
   practical difference in favor of DI (those still keeping the opposite   
   opinion, please present some new case with difference or point out   
   mistakes in reasoning upthread).   
      
   > 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.   
      
   How so? It is one of the popular approaches. (Unless you mean a   
   mandatory 1-1 mapping, after some size you build multiple executables.)   
      
   > You have to exclude the complete singleton implementation from the   
   > original code and replace it with a different one.   
      
   Sure, if the original is not fit, and you go for a mock, you leave out   
   the original or reroute the code to the same effect. That is hardly a   
   problem.   
      
   > In practice that means you have to replace some source files with others   
   > just for testing.   
      
   The usual way is the opposite one, you drag one source file for testing,   
   or a few.   
      
   > You cannot use the original binary to build your tests   
   > around it, but have to compile (at least link) everything again.   
      
   Hm? If we talk about a traditional static library, all you need is to   
   pack the implementation of the singleton in a separate object file.   
   Define your own version and link with the lib -- and it is left unlinked.   
      
   > Possibly even with different compiler settings.   
      
   But building the *unit* test suit separately is pretty common. Different   
   settings are no problem either.   
      
   While testing the image that you will deploy happens on different level,   
   where details about internal object passing are not seen in the first place.   
      
      
   --   
    [ 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)   
|