0

我正在使用 ceedling 对 C 应用程序进行单元测试,并试图实现 ~100% 的高覆盖率。

我的一个应用程序模块中有一个静态回调函数,它使用函数指针注册到 SDK 函数,并在 SDK 的某个事件中调用。

在 appModule.c 中,

typedef void( *type_appCallback ) ( void );

static void appCallback( void );

我想对这个函数进行单元测试,因为这个函数是静态的,所以不会在 ceedling test_appModule.c 中看到。我有一个解决这个定义的方法,TEST_STATIC而不是static,

#ifdef TEST 
TEST_STATIC
#else
TEST_STATIC static
#endif

但我不是这项工作的忠实拥护者,对上述问题有什么建议吗?

4

2 回答 2

0

我使用 CMock 回调插件做了类似于上面@Bodo 建议的事情。注意 cmockNumCalls 是存根函数的强制参数

生产代码 -> setCallback( funcAddress );

单元测试代码 -> setCallback_Stub(storeFuncAddress);

storeFuncAddress 的样子

void storeFuncAddress(
      type_appCallback       appCallbackFn,
      int                    cmockNumCalls)
{
    l_storedCallbackFn = appCallbackFn;
}

当 _Stub 版本被调用时,它会将相同的参数传递给注册的回调函数,因此 storeFuncAddress 接收相同的函数地址(它是指向静态的指针)并将其存储在我调用 l_storedCallbackFn 的 type_appCallback 类型的变量中。

第二部分是触发事件的地方。

生产代码 -> triggerCallback();

单元测试代码 -> triggerCallback_Stub( runStoredCallbackFunction );

我的 runStoredCallbackFunction 函数的样子

void runStoredCallbackFunction(
    int                       cmockNumCalls)
{
    (*l_storedCallbackFn)(NULL);
}

希望这可以帮助您或遇到同样问题的下一个人。

于 2021-10-07T19:38:13.270 回答
0

作为一种解决方法,您可以使用包含C文件的包装器模块。

wrap_app_Module.c

/* include code of static function (.c is intentional, not .h) */
#include "appModule.c"

void wrap_appCallback(void)
{
    appCallback();
}

static您可以在测试中调用包装函数,而不是函数。

于 2020-11-23T22:58:56.467 回答