Mock / Wrap静态函数由被测试的非静态函数调用

时间:2018-04-18 11:21:10

标签: c static mocking cmocka

我想通过使用cmocka框架实现单元测试来测试一些函数。

例如,我有一个正在测试的非静态函数,它调用两个静态函数。由于这些静态函数与硬件交互,我想模拟/包装它们并在测试时使用包装函数而不是实际函数。

与cmocka文档中描述的一样,我在构建/链接测试时使用了--wrap = myfunction链接器标记。

测试编译但是当我运行它们时,将调用真正的静态函数而不是包装。

当我声明静态函数是非静态函数时,它既不起作用也调用实函数。我发现的唯一解决方案是将功能外包到一个额外的.c文件中......但这是一个非常糟糕的解决方法,因为它非常操纵代码。

2 个答案:

答案 0 :(得分:1)

如果你的.c文件带有公共函数和两个静态函数,并且public函数调用静态函数,那么就无法阻止调用静态函数。毕竟,它们是一个编译单元。

你可以:

  • 整体测试

  • 使用#ifdef条件编译用简化的非硬件调用静态函数替换静态函数来测试公共函数

  • 使用#ifdef条件编译将公共函数替换为专用的公共函数来测试静态函数。

答案 1 :(得分:1)

正如@Paul所写,这就是static的工作原理,如果你想让gcc包装它们,函数需要在不同的编译单元中。通常,静态方法是私有实现细节,您不希望公开这些细节以进行测试。

所以要在另一个答案中添加更多选项:

  1. 显然,模拟这些函数而不用条件污染原始代码的最简单方法是将它们提取到一个单独的层(在本例中为HAL)。

  2. 您可以使#ifdef修饰符成为条件,这将允许使用cmocka进行换行。与一堆#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) { ... } s:

    相比,这对原始代码的污染较少
    current
  3. 使用objcopy来全局化和削弱所选的静态函数,如this answer中所述。