gpt4 book ai didi

cmocka,如何检查函数指针

转载 作者:行者123 更新时间:2023-11-30 16:36:50 25 4
gpt4 key购买 nike

我在文档和服务员示例中进行了搜索,但找不到有关如何检查正确的函数指针是否作为参数传递给函数的示例。

这个示例代码应该详细说明我的意思:

void func_A();
void func_B();

void verify(int value) {
if (value == 0) {
process(func_A);
} else if (value == 1) {
process(func_B);
}
}

我的想法是模拟这样的过程:

void __wrap_process(EVENT_HANDLER handler){
check_expected(handler);
///I made a test also with check_expected_ptr but the result is the same.
}

并且,在测试调用中:

expect_memory(__wrap_process, handler, func_A, sizeof(func_A));
verify(0);

这不起作用,因为如果我在expect_memory中将func_A替换为func_B,测试就会通过。除了 expect_memory 之外,我没有看到任何可以检查指针的 expect_* 函数。

你用了什么?

编辑:添加了以下示例。EDIT2:使用包含更新了示例并验证其编译是否正确。

作为示例,我可以提供这个简单的代码:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <stdint.h>
#include <cmocka.h>

union EVENT{
uint8_t event;
};

typedef void (*CALLBACK)(union EVENT * event);

void wrap_register_callback( CALLBACK callback );

void callback_module_a( union EVENT *event ) {
//Do something with the event
//It is out of scope for this test.
(void)event;
}

void callback_module_b( union EVENT *event ) {
//Do something with the event
//It is out of scope for this test.
(void)event;
}



void __wrap_register_callback( CALLBACK callback ) {
check_expected(callback);
}

void code_that_set_the_callback( int status ) {
if (status < 0){
register_callback(callback_module_a);
}else{
register_callback(callback_module_b);
}
}

void test_correct_handler( ) {
int status = 0;
expect_memory(__wrap_register_callback, callback, callback_module_a, sizeof(CALLBACK));
//TEST 1 expected result test pass. Result: test pass
code_that_set_the_callback(status);

status = -1;
expect_memory(__wrap_register_callback, callback, callback_module_b, sizeof(CALLBACK));
//TEST 2 expected result test pass. Result: test pass
code_that_set_the_callback(status);

//At the moment if I change the callbacks in the tests, like:
status = 0;
//This is not correct but the test passes.
expect_memory(__wrap_register_callback, callback, callback_module_b, sizeof(CALLBACK));
//TEST 3 expected result test fail. Result: test pass
//This is wrong
code_that_set_the_callback(status);

status = -1;
//This is not correct but the test passes.
expect_memory(__wrap_register_callback, callback, callback_module_a, sizeof(CALLBACK));
//TEST 4 expected result test fail. Result: test pass
//This is wrong
code_that_set_the_callback(status);
}

int main(void)
{
//Make coverage happy
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_correct_handler),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

代码说明:本测试代码中未测试函数register_callback。函数体被省略,因为在代码编译期间,将参数 -Wl,--wrap=register_callback 传递给链接器,该函数完全被 __wrap_register_callback 替换

这个想法是一个函数初始化一个回调,这个回调取决于一些初始化值。我想根据具体情况检查所选回调是否正确。

来自文档页面https://api.cmocka.org/group__cmocka__param.html

用于验证被模拟的函数接收的参数的可用宏不包含用于验证函数指针参数的函数。在我看来,我可以适应这个范围的唯一函数是expect_memory,但是

  • 它不起作用,
  • 我没有正确理解它的使用方法
  • 我在编写测试时犯了一个错误。

最佳答案

cmocka 似乎没有任何专门用于指针的参数检查宏。在许多 C 实现中,expect_value 可能会满足您的目的。 cmocka 将您传递给它的值转换为LargestIntegralType,它尝试将其定义为宽无符号整数类型。假设类型足够宽,许多 C 实现会将不同的指针转换为不同的整数,将相等的指针转换为相等的整数。 (C 中的两个指针可以比较为相等,即使它们内部具有不同的位表示形式。但是良好的 C 实现会在转换为整数时标准化表示形式。)

如果满足这些要求,您应该能够使用 expect_value 来测试指针,如下所示:

void test_correct_handler( ) {
int status = 0;
expect_value(__wrap_register_callback, callback, callback_module_a);
code_that_set_the_callback(status);

status = -1;
expect_value(__wrap_register_callback, callback, callback_module_b);
code_that_set_the_callback(status);

//At the moment if I change the callbacks in the tests, like:
status = 0;
//This is not correct but the test passes.
expect_value(__wrap_register_callback, callback, callback_module_b);
code_that_set_the_callback(status);

status = -1;
//This is not correct but the test passes.
expect_value(__wrap_register_callback, callback, callback_module_a);
code_that_set_the_callback(status);
}

对上面的修改确认它对使用 callback_module_a 还是 callback_module_b 很敏感。但是,测试的意义与您在问题中所说的相反:前两个报告失败,后两个报告通过。您确定您的测试方法正确吗?如果您在此代码中将 callback_module_acallback_module_b 交换,您将遇到您所请求的情况,其中前两个通过,后两个失败。

关于cmocka,如何检查函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48280727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com