You must not only make virtual methods, you must declare a pure virtual base class, and other classes use only the name of the virtual base class. Now you can use what we call the “Liskov signature principle”, and you can make as many specific subtypes of the abstract base class as you need. Since the abstract base class works just like the interface works in delphi, minus the counting part of the link, you get the best of both worlds. You can really just save your application code and thus reduce poor communication, as well as get a single test "composite objects" that you assembled yourself.
// in UnitBase.pas TMyClassBase = class public procedure Method1; virtual; abstract; procedure Method2; virtual; abstract; end; // in UnitReal.pas TMyClassReal = class(TMyClassbase) public procedure Method1; override; procedure Method2; override; end; // in UnitMock.pas TMyClassMock = class(TMyClassbase) public procedure Method1; override; procedure Method2; override; end;
In the place where "TMyClass" is used, change it to use TMyClassbase:
TMyOtherClass = class(TMyOtherClassBase) private FMyThing:TMyClassbase; public property MyThing:TMyClassBase read FMyThing write FMyThing; end;
By attaching TMyOtherclass at run time, you can decide whether to use a real or mock class:
// in my realapp.pas MyOtherClassObj := TMyotherClass.Create; MyOtherClassObj.MyThing := TMyOtherClassReal.Create; // real object // in my unittest.pas MyOtherClassObj := TMyotherClass.Create; MyOtherClassObj.MyThing := TMyOtherClassMock.Create; // mock object
(Remember to make a way to free MyOtherClassObj.MyThing later or you will have a leak)
Warren p
source share