For another easier pattern, like the one in the Mockito home page:

  TInterfaceMock.Create(TypeInfo(ICalculator),ICalc,self).
    ExpectsCount('Multiply',qoEqualTo,1).
    ExpectsCount('Add',[10,20],qoEqualTo,1);
  ICalc.Add(10,20);
  ICalc.Multiply(10,30)

If you want to follow the "test spy" pattern, you can use:

  Mock := TInterfaceMockSpy.Create(TypeInfo(ICalculator),ICalc,self);
  ICalc.Add(10,20);
  ICalc.Multiply(10,30)
  Mock.Verify('Add');
  Mock.Verify('Multiply',[10,30]);

If you compare with existing mocking frameworks, even in other languages / platforms like the two above, you will find out that the features included in mORMot are quite complete:

  • Stubbing of any method, returning default values for results; 
  • Definition of the stubbed behavior via a simple fluent interface, with TInterfaceStub.Returns(), including easy definition of returned results values, for the whole method or following parameters/arguments matchers; 
  • Handle methods with var, out or function result returned values - i.e. not only the function result (as other Delphi implementations does, due to a limitation of the TVirtualInterface standard implementation, on which mORMot does not rely), but all outgoing values, as an array of values; 
  • Stubbed methods can use delegates or event callbacks with TInterfaceStub.Executes() rule definitions, for the whole method or following parameters/arguments matchers, to run a more complex process; 
  • Stubbed methods can also raise exceptions with TInterfaceStub.Raises() rule definitions, for the whole method or following parameters/arguments matchers, if this is the behavior to be tested;
  • Clear distinction between mocks and stubs, with two dedicated classes, named TInterfaceStub and TInterfaceMock;
  • Mocks are directly linked to mORMot's unitary tests / test-driven classes;
  • Mocked methods can trigger test case failure with TInterfaceMock.Fails() definitions, for the whole method or following parameters/arguments matchers; 
  • Mocking via "expect-run-verify" or "run-verify" (aka "test spy") patterns, on choice, depending on your testing expectations; 
  • Mocking validation against number of execution of a method, or a method with arguments/parameters matchers, or the global execution trace - in this case, pass count can be compared with operators like < <= = <> > >= and not only the classic exact-number-of-times and at-least-once verification; 
  • Most common parameters and results definitions can be defined as simple array of const in the Delphi code, or by supplying JSON arrays (needed e.g. for more complex structures like record values); 
  • Execution trace retrieval in easy to read or write text format (and not via complex "fluent" interface e.g. with When clauses); 
  • Auto-release of the TInterfaceStub TInterfaceMock TInterfaceMockSpy generator instance, when the interface is no longer required, to minimize the code to type, and avoid potential memory leaks; 
  • Works from Delphi 6 up to XE3 - since no use of syntax sugar like generics, nor the RTTI.pas features; 
  • Very good performance (the faster Delphi mocking framework, for sure), due to very low overhead and its reuse of mORMot's low-level interface-based services kernel using JSON serialization, which does not rely on the slow and limited TVirtualInterface.

This article is part of a list of mocking/stubbing range of information:

Feedback is welcome on our forum, just as usual.