完全にC++のレガシーコードベースがあります。ビルドシステムはCMakeです。単体テストでの最初の試みは次のとおりです。
LibraryA
)。このライブラリには、テストするコードが含まれています。LibraryA
のCPPテストファイルごとに単体テストターゲットを定義し、LibraryA.lib
に対してリンクします。基本的に、ソース構造は次のようになります。
LibraryA/
Source/
Utils/
MyClass.cpp
MyClass.hpp
AnotherClass.cpp
AnotherClass.hpp
Network/
Socket.cpp
Socket.hpp
Tests/
Utils/
TestMyClass.cpp
TestAnotherClass.cpp
ここにあるのは、Source
内のTests
ディレクトリのミラー構造です。この構造により、コンパイラコマンドラインレベルでインクルードオーダートリックを使用して、モック目的でクラスヘッダーが見つかる場所に優先順位を付けることができます。 Tests
の下の各Test*.cpp
ファイルは、1つの実行可能ファイルになります。したがって、テストされるクラスごとに1つの実行可能テスト。
問題は、テスト実行可能ファイルでLibraryA.lib
に対してリンクしていることです。 Socketクラスをモックしたい場合、LibraryA.lib
にはすでにシンボルがコンパイルされているため、これはODR違反になります。シンボルを複製せずにモックすることはできないので、リンカが文句を言うでしょう。
ユニットテスト構造の全体的な設定は、モックに関しては、ビルドシステムの観点から大きな問題でした。
この問題の良い解決策はありますか?テスト構造への私のアプローチは完全に間違っていますか?
2つのオプションがあります。
リンク時依存性注入(最初のオプション)は、リンク時にコードを注入することを意味します。
Socket.hがSockerクラスを宣言し、Socket.cppがそれを実装する場合は、同じ名前のSocketでモッククラスを定義するヘッダーを追加します。元のソケットと同じ名前空間にある必要があります。
次に、単体テストをビルドするときに、Socket.cppをコンパイルしてリンクしないでください。モッククラスをコンパイルしてリンクし、ユニットテストで使用する必要があります。
シンプル:ライブラリをモックし(.ccファイルと.hファイルの両方をモックします)、同じライブラリが異なるテストで異なる方法でモックされるように準備します。