3

foo と呼ばれる C 構造体を宣言するとしましょう。この構造体には、bar と呼ばれる int フィールドと baz と呼ばれる char * があります。

Cmocka expect_check_expectedマクロを使用して、渡された構造が正しく、両方のフィールドに期待値があることを確認するにはどうすればよいですか? ドキュメントに例がある場合、私はそれを見逃しました。


[更新]おそらくexpect_check()を使用できますか? しかし、私は例を見つけることができません:-(

4

2 に答える 2

2

ほとんどの場合、構造体のメモリを比較するとうまくいくかもしれませんが、コンパイラがそこにいくつかのフィラー バイトを入れると、制御できないバイトがいくつかあり、ランダムな値を持つ可能性があります。これは、テストが常に同じ結果をもたらすとは限らないことを意味し、非常に面倒なデバッグ セッションにつながる可能性があります。

たとえば、次のような構造体があるとします。

typedef struct {
    uint8_t c;
    uint32_t i;
} tSomeStruct

ciが隣り合って配置され、5 を返すと思うかもしれませんsizeof( tSomeStruct )。しかし、これを試してみると、実際には 8 を返す可能性が高いことに驚かれることでしょうsizeof( tSomeStruct )。これは、前述のフィラー バイトによるものです。これらの他のバイトの値が何であるかはわかりません。構造体を使用する前に構造体を 0 に memset することでこれを回避できますが、これは少しハックであり、すべての場合に機能するとは限りません。

構造体をきれいな方法で比較するには、 cmocka と を使用できexpect_check( ... )ますcheck_expected( ... )。これにより、独自の比較関数を作成できるようになります。

これを使用する方法の例を次に示します (この例を変更しました: Cmocka Gitlab )

typedef struct {
    char c;
    int i;
} tSomeStruct;

void mock_function( tSomeStruct* param )
{
    check_expected(param)
}

/* return 1 = true, return 0 = false */
int my_int_equal_check(const LargestIntegralType value,
                    const LargestIntegralType check_value_data)
{
    tSomeStruct* cast_value = ( tSomeStruct* ) value;
    tSomeStruct* cast_check_value_data = ( tSomeStruct* ) check_value_data;    

    if ( ( cast_value->c == cast_check_value_data->c )
    && ( cast_value->i == cast_check_value_data->i ) ) {
        return 1;
    }

    return 0;
}

void mytest(void **state)
{
    tSomeStruct struct = {
        .c = 'c',
        .i = 'i',
    }

    expect_check(mock_function, param, my_int_equal_check, &struct);
}

ただし、構造体を関数へのポインターとして渡さない場合、チェック関数は LargestIntegralType しか使用しないため、これが可能かどうかはわかりません。

于 2020-09-21T14:04:24.963 に答える