/++
   An example of using mock objects to test a class.
   Demonstrates the use of ordered expectations.
 ++/

/**
   We want to pass calls through to the base class here,
   so instead of the usual interface, we'll be using a
   concrete class.
 **/
class IAssociate (T) {
   private T _item;

   uint calculate (ubyte[] data) { return data[0] < 12 ? 99 : data[0] % 127; }
   bool isStored (T item) { return _item == item; }
   void store (T item) { _item = item; }
}

class ToTest {
   private IAssociate!(real) _associate;
   
   public this (IAssociate!(real) associate) {
      _associate = associate;
   }

   uint calculate (real number, ubyte[] data) {
      if (!_associate.isStored(number)) {
         _associate.store(157.2342);
         return _associate.calculate(data);
      } else {
         return 0;
      }
   }

   unittest {
      // The mocker, as always.
      auto mock = new Mocker;
      // And the setup of data.
      auto associate = mock.mock!(IAssociate!(real));
      real number = 7.23;
      ubyte[] data = new ubyte[4];
      uint result = 42;

      // I don't care how or when or how often this is called;
      // but when it is, here's what to return.
      mock.allowing(associate.toString).returns("I'm a lumberjack and I'm okay");
      
      mock.expect(associate.isStored(number)).returns(false);
      associate.store(number);
      mock.lastCall.ignoreArgs;
      mock.expect(associate.calculate(data)).passThrough;
      
      mock.replay;

      auto target = new ToTest(associate);
      assert (target.calculate(number, data) == result);
      
      // Even though all the calls were passed through, dmocks still did the
      // accounting work for them, and made sure they were called the right
      // number of times with the right arguments.
      mock.verify;
   }
}

back to Examples