2009-07-14 21 views
16

Jak mogę przetestować metodę chronioną w C++?W jaki sposób mogę przetestować chronioną metodę w C++?

W języku Java, powinienem utworzyć klasę testową w tym samym pakiecie co testowana klasa lub utworzyć anonimową podklasę, która ujawnia metodę, której potrzebuję w mojej klasie testowej, ale żadna z tych metod nie jest dostępna dla mnie C++.

Testuję niezarządzaną klasę C++ przy użyciu NUnit.

+0

Czy używasz GenTestAsm-http: //www.codeproject.com/KB/applications/GenTestAsmBase.aspx? Lub jak inaczej działa niezarządzanego kodu C++ z NUNit (.NET)? – RichardOD

Odpowiedz

17

Zakładając, że oznacza chronioną metodę publicznie dostępnym zajęć:

w kodzie testowym zdefiniować klasę pochodną klasy badanego (bezpośrednio lub z jednym z jej klas pochodnych). Dodaj akcesory dla chronionych elementów lub przeprowadź testy w klasie pochodnej. "Zabezpieczona" kontrola dostępu naprawdę nie jest bardzo przerażająca w C++: nie wymaga żadnej współpracy z klasą bazową, aby "włamać się" do niej. Więc najlepiej, aby nie wprowadzać żadnych „kod testowy” do klasy bazowej, nawet deklaracja znajomego:

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

To jest prawdziwe zorientowane obiektowo rozwiązanie tego problemu. Dziedziczenie istnieje z jakiegoś powodu! –

0

Rozważ publiczną, być może statyczną funkcję "testu jednostkowego".

Brzydko, ale lepiej niż alternatywy, które mogę wymyślić przy użyciu makr lub znajomych lub takich.

2

Deklaracja przyjaciela klasy MyClass_UnitTest; w twojej MyClass. Następnie możesz zdefiniować MyClass_UnitTest w innym miejscu w swoim programie testów jednostkowych, który ma pełny dostęp do wewnętrznych elementów MyClass, ale nie musisz dostarczać implementacji w twojej aplikacji do wydawania. Zapoznaj się z dokumentacją CppUnit, aby zobaczyć, jak to zrobić.

+2

Zajęcia z przyjaciółmi są __not__ twoim przyjacielem. –

+1

Wtedy nic nie jest twoim przyjacielem. Każda cecha każdego języka może być niewłaściwie wykorzystana i nadużywana. Tylko dlatego, że idioci nadużywają tej funkcji, nie oznacza to, że nigdy nie powinienem jej używać do właściwego celu. –

+0

Uzgodniono, ale niektóre funkcje są łatwiejsze do nadużywania niż inne. Częściej niż nie, widzę funkcje znajomego używane do ominięcia enkapsulacji. –

2

używam CxxTest i mają CxxTest wywodzą się z klasy, który zawiera chronioną funkcję składową. Jeśli wciąż szukasz swojego ulubionego frameworka do testowania jednostkowego C++, spójrz na numer this article.

5

Można również używać za pomocą słowa kluczowego, aby odsłonić blok publicznego (za pomocą

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

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

0

Jest to proste rozwiązanie w C++ przy użyciu #define Wystarczy owinąć include swojego "ClassUnderTest" tak:

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

Credit goes to this article and RonFox

+1

W odpowiedzi na -1 ... Wiem, że w "teorii" powinieneś testować publiczny interfejs. Jednak w praktyce podczas cyklu rozwoju może to być nieoceniona sztuczka. Moja rada ... używaj go rozważnie. – Langley

Powiązane problemy