簡體   English   中英

cmocka,如何檢查函數指針

[英]cmocka, how to check a function pointer

我在文檔和服務員示例中進行了搜索,但是找不到如何檢查正確的函數指針是否作為參數傳遞給函數的示例。

此示例代碼應詳細說明我的意思:

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);

如果我更換這並不因為工作func_Afunc_B在expect_memory測試通過。 除了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_acallback_module_b是敏感的。 但是,測試的意義與您在問題中所說的相反:前兩個報告失敗,最后兩​​個報告通過。 您確定您的測試方法正確嗎? 如果在此代碼中將callback_module_acallback_module_b交換,則會遇到您所要求的情況,其中前兩個通過,后兩個失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM