ほとんどの場合、構造体のメモリを比較するとうまくいくかもしれませんが、コンパイラがそこにいくつかのフィラー バイトを入れると、制御できないバイトがいくつかあり、ランダムな値を持つ可能性があります。これは、テストが常に同じ結果をもたらすとは限らないことを意味し、非常に面倒なデバッグ セッションにつながる可能性があります。
たとえば、次のような構造体があるとします。
typedef struct {
uint8_t c;
uint32_t i;
} tSomeStruct
c
とi
が隣り合って配置され、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 しか使用しないため、これが可能かどうかはわかりません。