1

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

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

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

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

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

4

2 回答 2

4

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

因此,要为其他答案添加更多选项:

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

  2. 您可以使static修饰符有条件,这将允许使用 cmocka 进行包装。与一堆#ifdefs 相比,这对原始代码的污染更少:

    #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) {
       ... 
    }
    
  3. 使用 objcopy 来全球化和削弱选定的静态函数,如本答案中所述。

于 2018-04-18T13:32:01.437 回答
2

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

你可以:

  • 整体测试它们

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

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

于 2018-04-18T11:54:34.853 回答