/++
   An example of using mock objects to test a class.
   Demonstrates the PassThrough option.
 ++/

/**
   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 Associate (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 Associate!(real) _associate;
   
   public this (Associate!(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!(Associate!(real));
      real number = 7.23;
      ubyte[] data = new ubyte[4];
      uint result = 42;

      // In this case, I trust the existing class and am willing to have it manage
      // the method. However, I want to make sure that ToTest asks about the right
      // number -- this accomplishes that.
      mock.expect(associate.isStored(number)).passThrough;

      // Again, let the existing class deal with it, but this time I don't care
      // about the arguments.
      associate.store(number);
      mock.lastCall.ignoreArgs.passThrough;

      // And yet again.
      mock.expect(associate.calculate(data)).passThrough;

      // And continue with the rest of the test.
      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