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

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);
         writefln(_associate.toString);
         return _associate.calculate(data);
      } else {
         return 0;
      }
   }

   unittest {
      auto mock = new Mocker;
      auto associate = mock.mock!(IAssociate!(real));
      real number = 7.23;
      ubyte[] data = new ubyte[4];
      uint result = 42;

      mock.expect(associate.toString).repeatAny.returns("I'm a lumberjack and I'm okay");
      
      // Here we begin a block of ordered calls.
      // You can have unordered calls interspersed with ordered ones; that is,
      // this specifies a relative order between every expectation you add here,
      // but the toString expectation that I set up before can occur any number
      // of times between any calls in the ordered block.
      mock.ordered;
      mock.expect(associate.isStored(number)).returns(false);
      
      // I can still specify any attributes on these expectations that I want.
      associate.store(number);
      mock.lastCall.ignoreArgs;
      mock.expect(associate.calculate(data)).passThrough;
      
      // After this, any further expectations don't pay attention to order.
      mock.unordered;

      mock.replay();

      auto target = new ToTest(associate);
      assert (target.calculate(number, data) == result);
      
      mock.verify();
   }
}

back to Examples