我正在閱讀幾篇關於嘲諷C函數的文章(如CMock或CMocka),但我不確定在此過程中實際函數如何替換爲模擬函數。例如,CMocka依靠使用GNU編譯器的自動換行功能,該編譯器支持--wrap
等參數以將__wrap
前綴附加到函數調用,或弱符號,它們允許您覆蓋任何您喜歡的符號。在MSVC(Visual Studio)中嘲笑C函數
但是,你如何在Visual Studio中完成這項工作,幾乎所有其他框架?
例如,CMock has an example與此類似(簡化了很多在這裏):
// myfunc.c
#include <parsestuff.h>
// this is the function we would like to test
int MyFunc(char* Command)
{
// this is the call to the function we will mock
return ParseStuff(Command);
}
也有實際執行,它包含了實際功能的連接器,應在實際應用中發現:
// parsestuff.c
int ParseStuff(char* cmd)
{
// do some actual work
return 42;
}
現在,測試Ruby腳本期間創建像模擬功能:
// MockParseStuff.c (auto created by cmock)
int ParseStuff(char* Cmd);
void ParseStuff_ExpectAndReturn(char* Cmd, int toReturn);
但是如果VS項目已經包含
parsestuff.c
,那麼myfunc.c
的呼叫怎麼會以MockParseStuff.c
結尾呢?這是否意味着我不能在單元測試項目中包含
parsestuff.c
?但是,如果是這樣的話,那麼在任何測試中也不可能嘲笑,例如MyFunc
,從myfunc.c
,因爲我已經不得不包含它來測試它的文件了嗎?
(更新)我也知道,我可以包括.c
文件,而不是.h
文件,然後做一些預處理的東西來代替原來的呼叫,如:
// replace ParseStuff with ParseStuff_wrap
#define ParseStuff ParseStuff_wrap
// include the source instead of the header
#include <myfunc.c>
#undef ParseStuff
int ParseStuff_wrap(char* cmd)
{
// this will get called from MyFunc,
// which is now statically included
}
但是這看起來像很多管道,我甚至都沒有在任何地方看到它。
[這個問題](http://stackoverflow.com/q/33790425/1488067)問有關配置鏈接器來包裝函數的具體事情,但我相信它不可能在MSVC中。此外,CMocka提到了這一點,但CMock根本沒有提到這個要求。 – Lou
您是否需要在C++環境中模擬C-Style函數,還是隻有C環境?如果您可以使用C++,那麼您的問題就有一個非常簡單的解決方案,我可以提供一個示例。 – mrAtari
@mrAtari:它是Visual Studio,所以我可以混合使用C++和C,但是某些C代碼可能與C++不兼容(檢查[類似的問題])(http://softwarerecs.stackexchange.com/q/ 34878/22983))。但是,如果大多數情況下工作正常,那麼請提供一個例子說明C++如何解決這個問題 - 特別是如果它可以避免在生產代碼中添加任何與測試相關的預處理器指令。 – Lou