2009-07-14 7 views
16

Wie kann ich eine geschützte Methode in C++ testen?Wie kann ich eine geschützte Methode in C++ testen?

In Java würde ich entweder die Testklasse im selben Paket wie die zu testende Klasse erstellen oder eine anonyme Unterklasse erstellen, die die Methode in meiner Testklasse verfügbar macht, aber keine dieser Methoden steht mir zur Verfügung C++.

Ich teste eine nicht verwaltete C++ - Klasse mit NUnit.

+0

Verwenden Sie GenTestAsm-http: //www.codeproject.com/KB/applications/GenTestAsmBase.aspx? Oder wie sonst laufen Sie nicht verwalteten C++ - Code von NUNit (.NET)? – RichardOD

Antwort

17

Vorausgesetzt, dass Sie eine geschützte Methode einer öffentlich zugänglichen Klasse bedeuten:

Im Testcode definieren eine abgeleitete Klasse der Klasse unter Test (entweder direkt, oder aus einem ihrer abgeleiteten Klassen). Fügen Sie Zugriffsmethoden für die geschützten Member hinzu oder führen Sie Tests in Ihrer abgeleiteten Klasse durch. "Geschützte" Zugriffskontrolle ist in C++ wirklich nicht sehr beängstigend: Es bedarf keiner Kooperation von der Basisklasse, um "hineinzukriechen". So ist es am besten nicht „Testcode“ in die Basisklasse einzuführen, nicht einmal ein Freund Erklärung:

// in realclass.h 
class RealClass { 
    protected: 
    int foo(int a) { return a+1; } 
}; 

// in test code 
#include "realclass.h" 
class Test : public RealClass { 
    public: 
    int wrapfoo(int a) { return foo(a); } 
    void testfoo(int input, int expected) { 
     assert(foo(input) == expected); 
    } 
}; 

Test blah; 
assert(blah.wrapfoo(1) == 2); 
blah.testfoo(E_TO_THE_I_PI, 0); 
+0

Dies ist die wahre objektorientierte Lösung für dieses Problem. Vererbung existiert aus einem Grund! –

0

Betrachten Sie eine öffentliche, möglicherweise statische Unit-Test-Funktion.

Hässlich, aber besser als die Alternativen, die ich mit Makros oder Freunde oder so denken kann.

2

Eine Friend-Klasse deklarieren MyClass_UnitTest; in deiner MyClass. Sie können dann MyClass_UnitTest an anderer Stelle in Ihrem Komponententestprogramm definieren, das vollständigen Zugriff auf MyClass-Interna hat, aber Sie müssen keine Implementierung in Ihrer Freigabeanwendung bereitstellen. Ein gutes Beispiel dafür finden Sie in der Dokumentation CppUnit.

+2

Freund Klassen sind __not__ dein Freund. –

+1

Dann ist nichts dein Freund. Jedes Merkmal jeder Sprache kann missbraucht und missbraucht werden. Nur weil Idioten das Feature missbrauchen, heißt das nicht, dass ich es nie für seinen eigentlichen Zweck verwenden sollte. –

+0

Einverstanden, aber einige Funktionen sind leichter zu missbrauchen als andere. Meistens sehe ich Friend-Funktionen, um die Kapselung zu umgehen. –

2

Ich benutze CxxTest und habe die CxxTest aus der Klasse ableiten, die die geschützten Member-Funktion enthält. Wenn Sie immer noch nach Ihrem bevorzugten C++ Unit Testing-Framework suchen, werfen Sie einen Blick auf this article.

5

Sie auch öffentliche Block belichten können Schlüsselwort (mit

// in realclass.h 
class RealClass { 
    protected: 
    int foo(int a) { return a+1; } 
    int foo(string a) { return a.length(); } // Overload works too 
    template<class T> int foo(const T& a) { return 1; } // Templates work too 
}; 

// in test code 
#include "realclass.h" 
class RealClassExposed : public RealClass { 
    public: 
     using RealClass::foo; 
}; 

RealClassExposed blah; 
assert(blah.foo(1) == 2); 
assert(blah.foo("test") == 4); 
assert(blah.foo(blah) == 1); 

Siehe auch:.. http://en.cppreference.com/w/cpp/language/using_declaration

0

Es gibt eine einfache Lösung in C++ #define einfach wickeln die Ihrer "ClassUnderTest" schließen wie folgt aus:

#define protected public 
#define private public 
    #include <ClassUnderTest.hpp> 
#undef protected 
#undef private 

Credit goes to this article and RonFox

+1

Als Antwort auf die -1 ... Ich weiß in "Theorie" Sie sollten die öffentliche Schnittstelle testen. In der Praxis während des Entwicklungszyklus kann dies jedoch ein unschätzbarer Trick sein. Mein Rat ... benutze es vernünftig. – Langley