#c #unit-testing #cmock #ceedling
#c #модульное тестирование #cmock #ceedling
Вопрос:
Я использую 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
Но я не большой поклонник этой работы, какие-либо предложения по вышеуказанной проблеме?
Ответ №1:
В качестве обходного пути вы могли бы использовать модуль-оболочку, который включает файл C.
wrap_app_Module.c
/* include code of static function (.c is intentional, not .h) */
#include "appModule.c"
void wrap_appCallback(void)
{
appCallback();
}
Вместо static
функции вы можете вызвать функцию-оболочку в своих тестах.
Ответ №2:
Я сделал что-то похожее на то, что предложил @Bodo выше, используя плагин обратного вызова CMock. Примечание cmockNumCalls является обязательным параметром для функции stub
Производственный код -> setCallback( funcAddress );
Код модульного тестирования -> setCallback_Stub( storeFuncAddress);
Где storeFuncAddress выглядит как
void storeFuncAddress(
type_appCallback appCallbackFn,
int cmockNumCalls)
{
l_storedCallbackFn = appCallbackFn;
}
Когда вызывается версия _Stub, она передает те же параметры зарегистрированной функции обратного вызова, поэтому storeFuncAddress получает тот же адрес функции (который является указателем на статический) и сохраняет его в переменной типа type_appCallback, которую я вызываю l_storedCallbackFn.
Вторая часть — это то, где запускается событие.
Производственный код -> triggerCallback();
Код модульного тестирования -> triggerCallback_Stub( runStoredCallbackFunction );
Где моя функция runStoredCallbackFunction выглядит так
void runStoredCallbackFunction(
int cmockNumCalls)
{
(*l_storedCallbackFn)(NULL);
}
Надеюсь, это поможет вам или следующему человеку, который столкнется с этим же вопросом.