1

データベースにアクセスするメソッドを含む、大規模なレガシー コードベースのファイルがあります。クラスは使用されず、メソッド宣言を含むヘッダー ファイルと実装を含むソース ファイルのみが使用されます。

これらのメソッドをオーバーライドして、単体テスト中に DB アクセスを排除したいと考えています。

次のオプションを考えました。

  1. ファイルをクラスにしてメソッドをオーバーライドします。
    ここでの主な欠点は、コードベース全体に多くの変更が加えられることです。
    コードは改善されますが、理想的ではありません...
  2. ソース ファイル全体#ifdef PRODUCTION_CODEを でラップし、スタブを含む新しいソース ファイルを作成し、反対の方法でラップします。つまり、全体をコンパイルに依存させます。ここでの問題は、回帰テストを実行するビルド システムでは、アプリを作成して回帰テストを行うために 1 回、単体テストの実行可能ファイルを作成するために 2 回コンパイルする必要があることです。

これを行うための推奨される方法はありますか?

4

4 に答える 4

1

リンカー レベルでオーバーライドを試みることができます。DB インターフェイスを記述するヘッダーに関数を実装する 2 つの異なる .cpp ファイルを用意します。1 つは実際の DB を呼び出し、もう 1 つは偽のインターフェイスを呼び出します。単体テスト用にリンクするときは、一方を他方に置き換えます (GNU make のターゲット固有の変数が役立つ場合があります)。

于 2009-10-27T18:17:48.200 に答える
1

既存の関数を取得して、内部のコードを新しいクラスに移動し、既存の関数から新しいメソッドを呼び出して、テスト中にこのクラスをオーバーライドするのはどうですか?

そのようです:

 static DBAccessClass dac = new DBAccessClass ();

 void origFunction() { dac.origFunction(); }

そしてテストでは:

 dac = new DBAccessMockup();
于 2009-10-27T18:11:40.037 に答える
0

また、MichaelFeathersの著書「LegacyCodeで効果的に機能する」も参照してください。彼はこれらのタイプの問題について正確に説明しているだけでなく、この本には(Java、C、およびC#に加えて)C++の多数の例が含まれています。Feathersは、CppUnitの最初の作成者でもあります。

于 2009-11-18T13:39:20.187 に答える
0
  1. ファイルをクラスにしてメソッドをオーバーライドします。[...]
  2. ソースファイル全体を #ifdef でラップ [...]

可能であれば、データベース コード (X 関数の代わりにクラス ポインター) を集中的に参照する方法があるため、1 を使用します。つまり、モジュール性、実装の置き換え (スタブまたは別の DB バックエンドによる) の容易さ、およびよりカプセル化されたコードを意味します。

2 を使用する場合は、関数の実装を置き換えることを検討してください。つまり、元の関数内で、( に基づくif) テスト コードを実行します。

テスト環境で実行されているかどうかに関係なく、テストされたコードは完全に不可知であり、パフォーマンスの損失は無視できます (if(booleanFlagHere)ほとんどの場合、無視できるコストです)。テストされたコードを変更する必要はまったくありません)。

于 2010-06-18T09:15:28.663 に答える