Nehmen wir an, Sie haben ein sehr gut entwickeltes Delphi-Projekt, das die Abhängigkeitsinjektion und einige andere gute Praktiken berücksichtigt.
Nehmen wir nun an, Sie müssen eine Klasse vortäuschen, die wie folgt definiert ist:
%Vor% Method1
und Method2
sind nicht virtuell. Was machst du in diesem Fall? Um ein Objekt vorzuspielen, müssen wir es übernehmen und override
jede Methode, die Sie vortäuschen wollen, aber das ist in diesem Fall nicht möglich, weil sie nicht virtual
sind. Sollte ich den Quellcode so ändern, dass virtual
für jede Methode hinzugefügt wird, die ich nachahmen muss? Ist es nicht schlecht?
Bearbeiten
Ich habe überlegt, eine Compiler-Direktive zu erstellen, um alle Felder in der Klasse zu virtual
zu machen, ist das eine gute Idee? Nur meine Testsuite wird die Compiler-Direktive setzen.
EDIT2 *
Embarcadero sollte eine einfache Möglichkeit bieten, einen Methodenzeiger einer Klasse in einen anderen Methodenpunkt zu ändern, ohne dass virtual
benötigt wird.
Machen Sie die Methoden virtuell , damit Sie sie verspotten können. (Sie müssen nicht abstrakt sein.)
Wenn das nicht möglich ist, umschließt die Klasse mit einer anderen Klasse. Machen Sie die Methoden des Wrappers virtuell und leiten Sie in der Standardimplementierung nur Aufrufe an die ursprüngliche Klasse weiter. Überall dort, wo Ihr Programm die ursprüngliche Klasse verwendet, ersetzen Sie es durch den Wrapper. Spotte jetzt den Wrapper.
Um ein Objekt vorzuspielen, müssen wir es erben Es ist aber nicht möglich Fall.
Ich würde empfehlen, dass jede Klasse, die du sagst "Ich muss das nachahmen" sollte am Ende auf einer Schnittstelle basieren.
Mit anderen Worten, wenn Sie Methoden haben, die verspottet werden müssen, sollten sie in eine Schnittstelle eingefügt werden, und dann implementiert die zu mokierende Klasse diese Schnittstelle. Dann erstellen Sie den Schein, indem Sie die gleiche Schnittstelle im Scheinobjekt implementieren.
Die Alternative besteht darin, eine Mocking-Bibliothek zu verwenden. Sie können diese SO Frage betrachten:
Was ist Ihre Lieblingsspionierbibliothek von Delphi?
>und dieses Framework enthält auch spottende Objekte:
Das Verspotten von Objekten sollte auch die korrekte Verwendung der Abhängigkeitsinjektion in Ihrem Code fördern.
Sie sollten die Methoden nicht nur virtuell machen, Sie sollten eine reine virtuelle Basisklasse deklarieren und die anderen Klassen nur den reinen virtuellen Basisklassennamen verwenden lassen. Jetzt können Sie das verwenden, was wir das "Liskov-Substitutionsprinzip" nennen, und Sie können so viele konkrete Subtypen der abstrakten Basisklasse erstellen, wie Sie benötigen. Da die abstrakte Basisklasse genau so funktioniert, wie eine Schnittstelle in Delphi arbeitet, ohne den Referenzzähler, erhalten Sie das Beste aus beiden Welten. Sie können Ihren App-Code wirklich einfach halten und die schlechte Kopplung auf diese Weise reduzieren. Außerdem erhalten Sie Unit-testbare "Composite-Objekte", die Sie selbst erstellen.
%Vor%Ändern Sie an der Stelle, an der "TMyClass" verwendet wird, TMyClassbase:
%Vor%Wenn Sie TMyOtherclass zur Laufzeit verbinden, können Sie entscheiden, ob Sie die Real- oder die Scheinklasse verwenden möchten:
%Vor%(Vergessen Sie nicht, MyOtherClassObj.MyThing zu einem späteren Zeitpunkt freizugeben oder Sie werden ein Leck haben)
Tags und Links unit-testing delphi mocking