How do I make fun of a class that does not have virtual methods?

Suppose you have a very well-developed Delphi project that takes into account dependency injection and some other good practices.

Now suppose you need to make fun of a class defined as:

TMyClass = class public procedure Method1; procedure Method2 end; 

Method1 and Method2 are not virtual. What are you doing in this case? To mock an object, we need to inherit it and override every method that you want to make fun of, but this is not possible in this case, because they are not virtual . Do I have to modify the source code to add virtual for each method I need to make fun of? Isn't that bad?

Edit

I was thinking of creating a compiler directive to make all the fields in the virtual class, is this a good idea? Only my test suite will set the compiler directive.

EDIT2 *

Embarcadero should provide an easy way to change a class method pointer to another point in the method without the need for virtual .

+7
source share
3 answers

Make virtual methods so you can mock them. (They do not need to be abstract.)

If you cannot do this, end the class with another class. Make the shell methods virtual, and in the default implementation, just redirect the calls to the source class. Wherever your program uses the original class, replace it with a shell. Now, fool the wrapper.

+12
source

To make fun of an object, we need to inherit this, but this is not possible in this case.

I would recommend that every class you say “I need to mock this” should be based on an interface.

In other words, if you have methods that need to be mocked, they should be placed in the interface, and then the class that will be mocked implements this interface. Then you create the layout by implementing the same interface in the layout object.

An alternative is to use the Mocking library. You can look at this question:

What is your favorite default Delphi library?

and this structure includes mocking objects:

http://code.google.com/p/emballo/

Unclogging objects should also encourage the proper use of dependency injection in your code.

+6
source

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)

+5
source

All Articles