Let's assume you have a very well designed Delphi project, which respects the dependency injection and some other good practices.
Now let's assume you need to mock a class defined as:
TMyClass = class
public
procedure Method1;
procedure Method2
end;
Method1
and Method2
are not virtual. What do you do in this case? To mock an object we need to inherit it and override
every method you want to mock, but it is not possible in this case because they are not virtual
. Should I change the source code to add virtual
on every method I need to mock? Is not it bad?
Edit
I was thinking about creating a compiler directive to make all fields in the class to be virtual
, is it a good ideia? Only my test suite is going to set the compiler directive.
EDIT2*
Embarcadero should provide an easy way of changing a method pointer of a class to another method point, without the need for virtual
.
Mocking non-virtual methods and non-abstract classes means that you can mock a concreate instance of whichever class you like. JustMock allows you to create any mock object and test your code in complete isolation from its dependencies to achieve the best possible design for your software without making any sacrifices.
By default, methods are non-virtual, and they cannot be overridden. Virtual modifiers cannot be used with static, abstract, private, and override modifiers.
The non-virtual interface pattern (NVI) controls how methods in a base class are overridden. Such methods may be called by clients and overridable methods with core functionality. It is a pattern that is strongly related to the template method pattern.
It's possible to use Google Mock to mock a free function (i.e. a C-style function or a static method). You just need to rewrite your code to use an interface (abstract class). public: ... virtual bool Open(const char* path, const char* mode) { return OpenFile(path, mode); } };
Make the methods virtual so you can mock them. (They don't need to be abstract.)
If you cannot do that, then wrap the class with another class. Make the wrapper's methods virtual, and in the default implementation, just forward call calls to the original class. Wherever your program uses the original class, replace it with the wrapper. Now, mock the wrapper.
To mock an object we need to inherit it, but it is not possible in this case.
I'd recommend that every class that you say "I need to mock this" should end up being based on an interface.
In other words, if you have methods that need to be mocked, they should be put into an interface, and then the class to be mocked implements that interface. Then, you create the mock by implementing the same interface in the mock object.
The alternative is to use a Mocking library. You can look at these SO question:
What is your favorite Delphi mocking library?
and this framework includes mocking objects as well:
http://code.google.com/p/emballo/
Mocking objects should also encourage the proper use of dependency injection in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With