我正在阅读几篇关于嘲讽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