On 9/14/06, Scott Meyers <usenet@aristeia.com> wrote:

My understanding is that the ability to drop in mock objects requires
programming to an interface that can be either a "real" object or a mock
object, which in turn suggests using either a template parameter or a
base class.  Suppose, for example, you have this:

   class BigHonkinHairyClass {
   ...                            // expensive to construct
   };

and you want to implement some function f that takes a
BigHonkinHairyClass as a parameter.  The straightforward declaration
would be

   void f(BigHonkinHairyClass& bhhc);   // maybe const, doesn't matter

But now it's hard to drop in a mock.  So I assume you'd modify the
interface to be either

   template<typename T>
   void f(T& bhhc);               // T must more or less model
                                  // BigHonkinHairyClass

or this:

   class BigHonkinHairyBase {
   ...                            // interface to program against --
   };                             // uses virtuals

   class BigHonkinHairyClass: public BigHonkinHairyBase { ... };

   class MockHonkinHairyClass: public BigHonkinHairyBase { ... };

   void f(BigHonkinHairyBase& bhhc);

Is that correct?  In other words, you'd come up with an interface that
let clients do what they wanted but that was also mock-friendly for
testing purposes?  That is, you'd take testability into account when
designing your client interface?


I design interfaces like that, but not for testing - it's called the  Inversion Principle.  How often do you really need a BigHonkinHairyClass ?  Often, you really just need a subset of its interface.  So define that sub-interface.  Sometimes use templates,  sometimes inheritance, etc.

Maybe that doesn't apply for every function f() (ie a different interface for each function!?), but I thought the Inversion Principle would be worth mentioning; YMMV.

Tony