Am besten einfache Weise zu verspotten statische/Globale Funktion?
Habe ich eine einfache fast Wert-wie Klasse, wie z.B. Person:
class Person
{
public:
Person(ThirdPartyClass *object);
virtual ~Person(void);
virtual std::string GetFullName() const;
virtual int GetAge() const;
virtual int GetNumberOfDaysTillBirthday() const;
};
Ich bin mit einem Drittanbieter-Bibliothek und die ThirdPartyClass
braucht, um eine Globale/statische Funktion aufgerufen Destroy
(Teil der 3rd-party-Bibliothek) aufgerufen, es zu zerstören. Diese Destroy
Funktion wird aufgerufen, in der Person Destruktor.
Versuche jetzt, unit-test-meine Person-Klasse und ich brauche einen Weg, um mock/stub die Destroy
Methode. Ich glaube, ich könnte schreiben eine wrapper-Klasse um die statische Destroy
- Funktion und verwenden Sie dann dependency injection zu injizieren, diese wrapper in der Person-Klasse, aber es scheint wie overkill zu tun, nur um diese Funktion auf dieser einfach Klasse. Was ist eine einfache und unkomplizierte Möglichkeit, dies zu tun? Oder ist dependency injection wirklich der beste Weg, dies zu tun?
Update
Letztlich habe ich beschlossen zu gehen mit der Erstellung einer Klasse eingewickelt, dass alle 3rd-party-Bibliothek globalen Funktionen und dann mit dependency injection zu übergeben, die diese Klasse in den Konstruktor meiner Klasse "person". Auf diese Weise konnte ich die stub die Destroy-Methode. Obwohl die person-Klasse verwendet lediglich eine einzige Funktion, die anderen Funktionen der library aufgerufen werden, die an anderen Punkte in meinem code und da musste ich diese testen würde ich vor den gleichen Problem.
Ich erstellen Sie eine Instanz dieses wrapper-Klasse in meine main app-code und Spritzen, wo es gebraucht wird. Ich wählte diese route, weil ich denke, es ist klarer. Ich mag Billy ONeal Lösung und ich denke, es beantwortet meine Frage, aber ich habe gemerkt, wenn ich auf den code für ein paar Monate und kommen zurück, es würde mich länger, um herauszufinden, was Los war, als im Vergleich zu dependency injection. Ich bin erinnerte daran, dass das zen von python Aphorismus "Explizit ist besser als implizit." und ich fühle mich dependency injection macht, was geschieht, etwas expliziter.
- Was ist falsch mit nur die Erstellung einer statischen oder globalen Funktion als stub und nannte es?
- Gut, ich bin gerade erst in unit-Tests, aber mein Verständnis ist, dass Sie nicht möchten, ändern Sie die Klasse, die Sie testen, nur um es zu testen. Also, wenn ich Sie richtig verstehe, durch die Erstellung einer stub-Methode Destroy und mit, dass in meiner Klasse "Person" ich bin die änderung meiner person-Klasse und dann würd ich noch irgendwie wechseln Sie zwischen der Testversion und der Serienversion.
- nicht die Klasse ändern, testen, implementieren Ihre eigenen
ThirdPartyClass
vielmehr als ein stub. - Ich habe Stub
ThirdPartyClass
mit googlemock, aberThirdPartyClass
mussDestroy
aufgerufen, es zu bereinigen. - dann haben Sie einen Fehler in Ihrem code -
Person
aufrufen nichtDestroy
. Obwohl ich Sie fragte, wie es zu implementieren, wie Sie es nennen, ist etwas ganz anderes Problem. - Ich glaube nicht, Folgen Sie Ihnen. Zerstören ist eine Globale/statische Funktion, und es wird aufgerufen der Destruktor für die Klasse "Person" (als ich es schrieb).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen link erstellen, der Naht. Setzen Sie Ihr zerstören Deklaration in einem header -, und haben dann zwei Dateien Implementierung:
Und zum testen:
Verknüpfen Sie dann die erste Datei, die zu Ihren wichtigsten binären, und die zweite Datei für Ihre Tests binäre.
Über das, was Sie verlangen, ist unmöglich. Der linker backt Anrufe auf Globale Funktionen und statische Methoden in direkten Sprünge in die aufgerufene code -- es ist kein Nachschlage-oder Entscheidungsprozess hook zu erstellen jede Art von überlastung, wie Sie Sie bist auf der Suche nach (darüber hinaus mit
Destroy
Berufung etwas leichter verspottet).Einfach, verwenden Sie Typemock Isolator++ (disclaimer - ich arbeite dort)
Add 1 line-in Ihrem test zu fälschen/mock die
Destroy
global verwenden:
öffentlichen Statik verwenden:
private Statik verwenden:
Keine Notwendigkeit für zusätzliche code/Keine bedingte code /Keine verschiedenen links.
Ich bin einfach nur hier spielen, aber ein Ansatz, der möglicherweise Arbeit für Sie ist, um Ihren eigenen
destroy
Funktion und keine Verwechslungen der Forderung zu Gunsten von Sie es durch hinzufügen einer wrapper-Klasse um den Third_Party_Lib Zeiger...Einen Funktionszeiger schaffen würde, einen Weg zu ersetzen, um eine andere Implementierung. Außerdem ist es transparent für die Anrufer (es sei denn, Sie tun etwas wirklich dumm, wie der Aufruf
sizeof(funcname)
).