Как сопоставить поле структуры, которое передается по ссылке на издевательскую функцию?

#c #googletest #gmock

#c #googletest #googlemock

Вопрос:

У меня есть следующая структура :

     struct can_frame {
        canid_t can_id;  /* 32 bit CAN_ID   EFF/RTR/ERR flags */
        __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
        __u8    __pad;   /* padding */
        __u8    __res0;  /* reserved / padding */
        __u8    __res1;  /* reserved / padding */
        __u8    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
    };
  

Я передаю структуру по ссылке на издевательскую функцию :
MOCK_METHOD1(write, int(can_frame* frame));

Я хотел бы сопоставить, имеет ли структура passes заданный номер в поле данных: EXPECT_CALL(*canSocketMock_, write(**if the value of can_frame->data[1] is equal to 10, else assert false**))).WillOnce(Return(16));

Я попытался объединить средства сопоставления Pointee, Field и ArrayElement, но не смог создать то, что хотел. Синтаксис сопоставителей для меня слишком запутанный.

Редактировать: Тест:

 TEST_F(SchunkDeviceShould, applyBreakWritesRightMessage) {
ASSERT_NO_THROW(sut_.reset(new SchunkDevice(
        canSocketMock_, 3)));
can_frame frame;
EXPECT_CALL(*canSocketMock_, write(FrameDataEquals(amp;frame, 1, CMD_STOP)))).WillOnce(Return(16));
ASSERT_TRUE(sut_->applyBreak());
}
  

Функция, которую мы вызываем:

 bool SchunkDevice::applyBreak() {
    can_frame frame;
    frame.can_id = MESSAGE_TO_DEVICE canID_;
    frame.can_dlc = 0x02;
    frame.data[0] = frame.can_dlc - 1;
    frame.data[1] = CMD_STOP;
    if (int len = socket_->write(amp;frame) != 16) {
        return false;
    }
    return true;
}
  

Вывод теста:

 Unexpected mock function call - taking default action specified at:
/home/../SchunkDeviceTests.cpp:47:
    Function call: write(0x7ffc27c4de60)
          Returns: 16
Google Mock tried the following 1 expectation, but it didn't match:

/home/../SchunkDeviceTests.cpp:457: EXPECT_CALL(*canSocketMock_, write(FrameDataEquals(amp;frame, 1, CMD_STOP)))...
  Expected arg #0: frame data equals (0x7ffc27c4def0, 1, 145)
           Actual: 0x7ffc27c4de60
         Expected: to be called once
           Actual: never called - unsatisfied and active
  

Ответ №1:

Вы могли бы определить пользовательский сопоставитель для проверки содержимого структуры.

 MATCHER_P2(FrameDataEquals, index, value, "") { return (arg->data[index] == value); }
  

Затем вы могли бы использовать его следующим образом:

 EXPECT_CALL(mock, write(FrameDataEquals(1, 10))).WillOnce(Return(16));
  

Комментарии:

1. почему-то это никогда не соответствует аргументу, ожидаемый аргумент # 0 не соответствует. Я думаю, что этот механизм сопоставления проверяет ссылку на ранее объявленный can_frame с той, которая передается ему позже, и они не совпадают.

2. Я добавил детали к вопросу, спасибо за помощь

3. @valikund Извините, мой пример был неправильным, вам не нужно на самом деле передавать фрейм. Не уверен, о чем я думал в то время. Обновлен ответ.