问题描述
我想通过使用cmocka框架实现单元测试来测试某些功能.
I would like to test some functions by implementing unit tests with cmocka framework.
例如,我有一个受测试的非静态函数,它调用了两个静态函数.由于这些静态功能会与硬件交互,因此我想对它们进行模拟/包装,并在测试时使用包装功能而不是真实功能.
For example I have a non-static function under test which calls two static functions. Because of the fact that these static functions interact with hardware I want to mock/wrap them and use a wrap function instead of the real function when testing.
就像cmocka文档中所述,我在构建/链接测试时使用了--wrap = myfunction链接器标志.
Like described in the cmocka documentation I've used the --wrap=myfunction linker flags when building/linking my tests.
测试可以编译,但是当我运行它们时,将调用真正的静态函数而不是自动换行.
The tests compile but when I run them the real static functions will be called instead of the wraps.
当我声明静态函数为非静态时,它也不起作用,并且还会调用真实函数.我发现的唯一解决方案是将功能外包给一个额外的.c文件...但这是一个非常糟糕的解决方法,因为它会非常操纵代码.
When I declare the static functions non-static it doesn't work either and also the real functions are called. The only solution I've found is to outsource the functions in an extra .c-file...but that's a really bad workaround because it manipulates the code very much.
推荐答案
正如@Paul所写,这只是--wrap
的工作方式,如果您希望gcc封装函数,则这些函数必须位于不同的编译单元中.通常,静态方法是您不想公开进行测试的私有实现细节.
As @Paul wrote, this is simply how --wrap
works, the functions need to be in a different compilation unit if you want gcc to wrap them. Generally, static methods are private implementation details which you don't want to expose for testing.
因此要为其他答案添加更多选项:
So to add some more options to the other answer:
-
很明显,模拟这些函数而不用条件句污染原始代码的最简单方法是将它们提取到一个单独的层(在本例中为HAL).
Obviously, the simplest way to mock these functions without polluting the original code with conditionals is to extract them into a separate layer (in this case, a HAL).
您可以将static
修饰符设为有条件的,这将允许使用cmocka进行包装.与一堆#ifdef
s相比,这对原始代码的污染更少:
You can make the static
modifier conditional, which will allow wrapping with cmocka. This does less polluting to the original code than a bunch of #ifdef
s:
#ifndef UNIT_TESTING
# define mockable_static static
#else
# define mockable_static
#endif
// then, replace 'static' with 'mockable_static'
mockable_static void some_static_method(void) {
...
}
使用objcopy全球化和削弱所选的静态函数,如此答案中所述.
Use objcopy to globalize and weaken selected static functions, as explained in this answer.
这篇关于模拟/包装被测试的非静态函数调用的静态函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!