2009-07-14 15 views
16

Come si esegue il test dell'unità in un metodo protetto in C++?Come posso testare unitamente un metodo protetto in C++?

In Java, creerei la classe di test nello stesso pacchetto della classe sottoposta a test o creerò una sottoclasse anonima che espone il metodo di cui ho bisogno nella mia classe di test, ma nessuno di questi metodi è disponibile per me C++.

Sto testando una classe C++ non gestita utilizzando NUnit.

+0

Stai usando GenTestAsm-http: //www.codeproject.com/KB/applications/GenTestAsmBase.aspx? O in quale altro modo si sta eseguendo codice C++ non gestito da NUNit (.NET)? – RichardOD

risposta

17

Supponendo si intende un metodo protetto di una classe accessibile al pubblico:

Nel codice di test, definire una classe derivata della classe in prova (direttamente, o da uno dei suoi classi derivate). Aggiungi accessor per i membri protetti o esegui test all'interno della tua classe derivata. il controllo degli accessi "protetto" non è molto spaventoso in C++: non richiede alcuna cooperazione da parte della classe base per "penetrare" in esso. Quindi è meglio non introdurre alcun "codice di prova" in classe di base, nemmeno un amico dichiarazione:

// 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

Questa è la vera soluzione orientata agli oggetti a questo problema. L'ereditarietà esiste per una ragione! –

0

Si consideri una funzione di test unitario pubblica, possibilmente statica.

Ugly, ma meglio delle alternative Posso pensare di utilizzare macro o amici o simili.

2

Dichiarare una classe di amici MyClass_UnitTest; nella tua MyClass. È quindi possibile definire MyClass_UnitTest altrove nel programma di test dell'unità che ha accesso completo agli interni di MyClass, ma non è necessario fornire un'implementazione nell'applicazione di rilascio. Vedere la documentazione CppUnit per un buon esempio di come è fatto.

+2

Le classi di amici non sono __not__ i tuoi amici. –

+1

Quindi niente è tuo amico. Ogni caratteristica di ogni lingua può essere usata impropriamente e abusata. Solo perché gli idioti usano male la funzione non significa che non dovrei mai usarla per il suo scopo. –

+0

Concordato, ma alcune funzioni sono più facili da abusare rispetto ad altre. Il più delle volte, vedo le funzioni di un amico utilizzate per aggirare l'incapsulamento. –

2

utilizzare CxxTest e hanno il CxxTest derivare dalla classe che contiene la funzione membro protetto. Se stai ancora cercando il tuo framework C++ per il test delle unità preferito, dai un'occhiata a this article.

5

È inoltre possibile utilizzare tramite parola chiave per esporre blocco pubblico (usando

// 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); 

See:.. http://en.cppreference.com/w/cpp/language/using_declaration

0

C'è una soluzione semplice in C++ usando #define Basta avvolgere l'inclusione del "ClassUnderTest" in questo modo:

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

Credit goes to this article and RonFox

+1

In risposta al -1 ... So che in "teoria" si dovrebbe testare l'interfaccia pubblica. Tuttavia, in pratica durante il ciclo di sviluppo questo può essere un trucco inestimabile. Il mio consiglio ... usalo con giudizio. – Langley

Problemi correlati