Amop 是一款開源的自動 Mock 工具,利用虛函數表機制實現對虛函數的模擬。與其他 C++ Mock 框架不同,Amop 最大的優勢在於無需手動實現虛擬類,完全由框架自動處理,極大簡化了使用流程。然而,Amop 大量使用了模板特性,而 Visual C++ 6.0 發布於 C++ 標準確立之前,對模板的支援極其有限,導致在 VC6 環境下直接使用 Amop 面臨重重困難。
經過深入探索,筆者發現透過整合 Intel C++ 編譯器(版本 8/9)到 VC6 IDE 中,可有效解決編譯問題。Intel 編譯器對模板的支援較好,且持續更新版本。但在實際編譯測試中,由於 Amop 直接操作虛函數表,許多特性與編譯器實現緊密相關,仍需捨棄部分功能(如解構函數 Mock、char* 類型參數比較)才能在 VC6 + Intel 編譯器環境下穩定運行。
由於更換編譯器需重新編譯庫文件,將 Amop 的頭文件與庫文件放置於 $(LLT_PATH)\Amop 目錄,並在專案中進行以下設定:
/I "$(LLT_PATH)\Amop\include"/libpath:"$(LLT_PATH)\Amop\lib\VC6\Intel9.1"Amop.lib 加入專案連結。MockObject.h 並使用 amop 命名空間。假設測試介面為 IInterface,定義 Mock 對象語法如下:
TMockObject<IInterface> mock;
針對介面中的虛函數 SimpleFunction:
mock.Method(&IInterface::SimpleFunction);
若未設定,呼叫該函數時將拋出 TNotImplementedException 異常。
mock.Method(&IInterface::ComplexFunction).Will("Test Result");Wills,設定的回傳值數量必須與實際呼叫次數一致,否則拋出異常。使用 Throw / Throws 設定特定異常:
mock.Method(&IInterface::SimpleFunctionWithReturn).Throws(SimpleException(22));
使用 Expect / Expects 驗證參數,模板參數代表參數索引(從 0 開始)。實際參數與期望值不符時拋出異常。
使用 Set / Sets 設定輸出參數,尖括號內為輸出參數序號(從 0 開始)。
Count() 可獲取或設定預期呼叫次數,配合 Verify 驗證實際執行情況。
測試用例中務必呼叫 Verify,確保執行流程符合預期,避免靜默失敗。
使用 Clear 重置指定函數的 Mock 行為。
使用 Redirect 將呼叫導向另一個函數,相當於打樁操作。
VC6 發布於 1998 年左右,而 C++ 國際標準 (ISO/IEC 14882) 直到 1998 年 9 月才由 ITTF 正式發布。VC6 開發時 C++ 標準尚在草案階段(CD/FDIS 投票中),這解釋了其模板支援不足的歷史原因。
/nodefaultlib:"LIBCPD.lib" /nodefaultlib:"LIBCD.lib",統一 UnitTest++ 與 Amop 的編譯選項為 /MDd 後解決。const char* 判定為不同參數而拋出異常,改用 std::string 即可繞過。#endif 後註解導致編譯錯誤:將註解移至下一行即可修正。更完整的帶圖解版本請參考原文附件。本文出自「果凍的軟件技術博客」。