【问题标题】:Mock/Wrap static functions called by a non-static function under test被测试的非静态函数调用的 Mock/Wrap 静态函数
【发布时间】:2018-09-28 14:55:23
【问题描述】:

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

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

如 cmocka 文档中所述,我在构建/链接测试时使用了 --wrap=myfunction 链接器标志。

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

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

【问题讨论】:

    标签: c static mocking cmocka


    【解决方案1】:

    正如@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 来全球化和削弱选定的静态函数,如 this answer 中所述。

    【讨论】:

    • 谢谢格鲁。我通过创建一个单独的层(HAL)解决了这个问题。现在这些函数是非静态的,我可以轻松地模拟它们。
    【解决方案2】:

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

    你可以:

    • 对它们进行整体测试

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 2014-10-28
      相关资源
      最近更新 更多