115

私はいくつかの単体テストを書いている最中です。特に、いくつかのプライベート メソッドをテストしたいと考えています。

これまでのところ、私は使用することを思いつきました。

#define private public

しかし、単体テストの観点からすべてのカプセル化を破壊するので、これには満足していません。

プライベート メソッドの単体テストに使用するメソッド。

4

8 に答える 8

84

質問で言及した厄介なハックではなく、より#defineクリーンなメカニズムは、テストをテスト対象のクラスのフレンドにすることです。これにより、テスト コード (およびテスト コードのみ) がプライベートにアクセスできるようになり、他のすべてのものから保護されます。

ただし、パブリック インターフェイスを介してテストすることをお勧めします。クラス X のプライベート メンバー関数に多くのコードがある場合は、クラス X の実装で使用される新しいクラス Y を抽出する価値があるかもしれません。この新しいクラス Y は、公開インターフェイスを公開せずに、パブリック インターフェイスを介してテストできます。クラス X のクライアントに使用します。

于 2010-09-09T12:58:37.240 に答える
73

Google Test を使用している場合は、FRIEND_TESTを使用して、テスト フィクスチャをテスト対象のクラスのフレンドとして簡単に宣言できます。

そして、ご存知のように、他の回答のいくつかが言っているように、プライベート関数のテストが明らかに悪い場合は、おそらく Google Test に組み込まれません。

この回答で、プライベート関数のテストが良い場合と悪い場合について詳しく読むことができます。

于 2012-05-31T21:45:14.530 に答える
70

メソッドが複雑で、単独でテストする必要がある場合は、メソッドを独自のクラスにリファクタリングし、パブリックインターフェイスを介してテストします。次に、元のクラスでそれらをプライベートに使用します。

于 2010-09-09T12:53:29.070 に答える
34

元のクラスのフレンドとしてテスト クラスを作成します。このフレンド宣言は#define UNIT_TESTフラグの内側になります。

class To_test_class {
   #ifdef UNIT_TEST
     friend test_class;
   #endif
}

単体テストのために、コードを flag でコンパイルします-DUNIT_TEST。このようにして、プライベート関数をテストできます。

UNIT_TESTフラグが false になるため、単体テスト コードは本番環境にプッシュされなくなります。したがって、コードは依然として安全です。

また、単体テスト用の特別なライブラリは必要ありません。

于 2010-09-09T13:25:43.457 に答える
5

定義ハックは恐ろしい考えです。コードをコンパイルするときに、プリプロセッサを使用して任意にコードを書き直すことは決して賢明ではありません。

何人かがすでに述べているように、プライベート メソッドをテストする必要があるかどうかは議論の余地があります。ただし、インスタンス化を特定のスコープに制限するために意図的にコンストラクターを非表示にした場合や、その他のいくつかの難解なケースはカバーされません。

また、名前空間をフレンドにすることはできず、「フレンドシップ」は C++ では継承されないため、単体テスト フレームワークによっては問題が発生する可能性があります。幸いなことに、Boost.Test を使用している場合は、Fixtures の形でこの問題を解決する洗練された方法があります。

http://www.boost.org/doc/libs/1_52_0/libs/test/doc/html/utf/user-guide/fixture/per-test-case.html

フィクスチャをフレンドリにして、単体テスト関数で使用するすべてのインスタンスをインスタンス化し、それらをフィクスチャに対して静的であり、モジュール スコープで宣言することができます。名前空間を使用している場合でも、心配する必要はありません。名前空間内でフィクスチャを宣言し、名前空間外でテスト ケースを宣言してから、スコープ解決演算子を使用して静的メンバーにアクセスできます。

マクロは、BOOST_FIXTURE_TEST_CASEフィクスチャのインスタンス化と破棄を処理します。

于 2012-12-12T23:28:16.100 に答える
0

プライベート メソッドには単体テスト ケースは必要ないと思います。

メソッドがプライベートの場合、そのクラス内でのみ使用できます。このプライベート メソッドを使用してすべてのパブリック メソッドをテストした場合、これを個別にテストする必要はありません。

于 2010-09-09T13:00:39.733 に答える