2009-07-14 25 views
16

保護されたメソッドをC++で単体テストする方法を教えてください。C++で保護されたメソッドを単体テストするにはどうすればよいですか?

Javaでは、テスト対象のクラスと同じパッケージにテストクラスを作成するか、テストクラスで必要なメソッドを公開する匿名サブクラスを作成しますが、どちらのメソッドも使用できませんC++。

NUnitを使用してアンマネージC++クラスをテストしています。

+0

GenTestAsm-http://www.codeproject.com/KB/applications/GenTestAsmBase.aspxを使用していますか?または、NUNit(.NET)からアンマネージC++コードをどのように実行していますか? – RichardOD

答えて

17

あなたは公的にアクセス可能なクラスの保護された方法を意味すると仮定すると:テスト対象クラスの派生クラスを定義し、テストコードで

を(直接的に、またはその派生クラスのいずれかから)。保護されたメンバーのアクセサを追加するか、派生クラス内でテストを実行します。 "保護された"アクセスコントロールは、C++では本当にあまり恐ろしいことではありません。基本クラスとの協調は必要ありません。

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

これは、この問題に対する真のオブジェクト指向のソリューションです。理由のために継承が存在する! –

0

静的な「単体テスト」機能を公開することを検討してください。

醜いですが、私はマクロや友人などを使って考えることができます。

2

友人クラスを宣言するMyClass_UnitTest;あなたのMyClassで。 MyClass内部にフルアクセスできるユニットテストプログラム内の別の場所にMyClass_UnitTestを定義できますが、リリースアプリケーションに実装を提供する必要はありません。 これがどのように行われたかの良い例は、CppUnitのドキュメントを参照してください。

+2

フレンドクラスはあなたの友人を__not__しています。 –

+1

あなたの友人は何もありません。すべての言語のあらゆる機能が悪用され、虐待される可能性があります。馬鹿がこの機能を悪用しているからといって、私はその機能を決して使ってはいけません。 –

+0

合意しましたが、一部の機能は他の機能よりも悪用しやすいです。多くの場合、カプセル化を回避するために使用されるフレンド機能があります。 –

2

私はCxxTestを使用して保護されたメンバ関数を含むクラスから派生CxxTestを持っている:だから、いなくても友人宣言、基底クラスに任意の「テスト・コード」を導入しないことが最善です。あなたが好きなC++ Unit Testingフレームワークをまだ探しているなら、this articleを見てください。

5
あなたはまた、公共のブロックを公開するために、キーワードを使用して使用することができます

(使用

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

を参照してください:。。http://en.cppreference.com/w/cpp/language/using_declaration

0

の#defineを使ってC++で簡単な解決策はありますちょうどあなたの「ClassUnderTest」の含まラップこのような:

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

Credit goes to this article and RonFox

+1

-1に応答して...私は "理論"であなたがパブリックインターフェイスをテストするべきであることを知っています。しかし、実際には開発サイクル中に、これは非常に貴重なトリックになる可能性があります。私のアドバイス...それを賢明に使ってください。 – Langley

関連する問題