2013-02-09 5 views
12

Ich arbeite an einem prozeduralen C/C++ - Projekt. Die öffentliche Schnittstelle besteht aus 4 Funktionen mit jeweils sehr komplexen Aufgaben. Es gibt Hilfsfunktionen, die in derselben Datei cpp in einem unbenannten Namensbereich deklariert sind. Als Testframework wird GTest verwendet.Unit Testing C++ - Code in einem Unbenannte Namespace

Einige dieser Hilfsfunktionen werden jedoch komplex genug, um ihre eigenen Komponententests zu erfordern. Normalerweise würde ich diese Helfer in ihre eigenen testbaren Einheiten umgestalten, aber der Projektanforderungen zufolge muss alles in dem einen sein cpp, und nur die angegebenen Funktionen können öffentlich sichtbar sein.

Gibt es eine Möglichkeit, die Hilfsfunktionen zu testen und gleichzeitig die Kopplung zu minimieren und den Projektanforderungen so genau wie möglich zu folgen?

Eine mögliche Lösung, die ich hatte, bestand darin, einen Makro zu verwenden, um den Namespace in einen benannten zum Testen und unbenannt für die Produktion zu verwandeln. Allerdings schien das ein bisschen unordentlicher als ich es gerne hätte.

+0

Mögliches Duplikat von [Wie teste ich eine Klasse mit privaten Methoden, Feldern oder inneren Klassen?] (Https://stackoverflow.com/questions/34571/how-do-i-test-a-class-that -has-private-methods-fields-or-inner-classes – Raedwald

Antwort

12

Beide Definitionen und Deklarationen in einem anonymen namespace sind nur innerhalb derselben Übersetzungseinheit sichtbar.

Es gibt zwei Möglichkeiten, diese privaten Funktionen zu testen.

Sie können die gesamte Datei .cpp#include in Ihrer _test.cpp Datei getestet. (#include ing .cpp Dateien ist kein guter Weg, um Code wiederverwenden - Sie sollten dies in der Produktion Code nicht!)

Vielleicht ein besserer Ansatz ist es, den privaten Code in ein foo::internalnamespace zu bewegen, wo foo ist das namespace Ihr Projekt normalerweise verwendet, und legen Sie die privaten Deklarationen in eine -internal.h Datei. Ihre Produktion .cpp Dateien und Ihre Tests dürfen diesen internen Header enthalten, aber Ihre Clients nicht. Auf diese Weise können Sie Ihre interne Implementierung vollständig testen, ohne sie an Ihre Kunden zu verlieren.

+0

Danke, das hilft sehr. –

+6

Bei der zweiten Methode bedeutet das Verschieben von Objekten in den benannten Namespace, dass die referenzierbare Laufzeitidentität erhalten bleibt. Der Grund für die Verwendung anonymer Namespaces scheint ungültig zu sein. Ein Zugriff aus der Compilierungseinheit wird komplett verhindert ... – Eonil

+0

Wirklich mag deine erste Idee. Ich frage mich, ob jemand mich dafür erschießen wird. – zehelvion