C-строка никогда не будет вызываться в gmock

У меня есть функция C++ для тестирования, и внутри этой функции C++ она вызовет функцию C. Я хотел бы издеваться над этой функцией C, используя Gmock. Сигнатура функции C:

int functionA(const char key[3],char value[6]);

int — это код возврата, ввод — key, вывод — value. Я хочу издеваться над возвращаемым значением и установить второй аргумент.

Функция С++, которую я хотел бы протестировать:

int functionB{
     ....
     int rcode = functionA(key, value);
     .......
}

Мой "mock.h":

#include<functionA.h>
#include <gmock/gmock.h>
class function_A_interface {
public:
   virtual int functionA(const char key[3],char value[6]) = 0;
};

class function_A_mock : public function_A_interface {
public:
   MOCK_METHOD2(functionA, int(const char[3], char[6]));
}

Мой "mock.cc":

#include <function_A_mock.h>
extern function_A_mock MockObj;
int function_A(const char key[3],char value[6])
{
    return MockObj.functionA(key, value);
}

Мой "test.t.cpp":

TEST(Test, tes){

function_A_mock MockObj;
 pa[3] = {0};
 pb[6] = {1};
 EXPECT_CALL(MockObj, functionA(pa, pb)).WillOnce(DoAll(SetArgPointee<1>(*set), Return(3)));

  functionB(parameter1, parameter2); // it will convert these two paramters to according input in functionA
}

но он показывает мне:

Unexpected mock function call - returning default value.
    Function call: functionA(ffbfc5b0 pointing to "abc      E", ffbfc570 pointing to "")
          Returns: 0
Google Mock tried the following 1 expectation, but it didn't match:

test.t.cpp:121: EXPECT_CALL(MockObj, functionA(pa, pb))...
  Expected arg #0: is equal to ffbfd380 pointing to "abc      E"
           Actual: ffbfc5b0 pointing to "abc      E"
  Expected arg #1: is equal to ffbfd340 pointing to ""
           Actual: ffbfc570 pointing to ""
         Expected: to be called once
           Actual: never called - unsatisfied and active

Кажется, я никогда не мог сопоставить параметры, которые я установил, поэтому он никогда не будет вызываться. Как в моем случае издеваться над строкой C как для совпадения, так и для установки аргумента? Спасибо.


person coder    schedule 11.06.2019    source источник


Ответы (1)


Если вы не предоставляете какой-либо другой Matcher для имитации аргументов функции, предполагается Eq(). Eq() сопоставитель очень прост - он сравнивает полученный аргумент с ожидаемым аргументом, используя operator ==. Но для строк в стиле C это сравнение сравнивает указатели, а не фактические строки.

Вместо этого вы должны использовать StrEq matcher для сравнения:

using ::testing::StrEq;
EXPECT_CALL(MockObj, functionA(StrEq(pa), StrEq(pb)))
       .WillOnce(DoAll(SetArgPointee<1>(*set), Return(3)));

Однако StrEq() будет сравнивать вещи как строки с завершающим нулем. Если вы хотите вместо этого сравнить целые массивы, используйте ElementsAreArray(array, count):

EXPECT_CALL(MockObj, functionA(ElementsAreArray(pa, 3), ElementsAreArray(pb, 6)))
       .WillOnce(DoAll(SetArgPointee<1>(*set), Return(3)));
person Yksisarvinen    schedule 11.06.2019
comment
Спасибо @Yksisarvinen, мне тоже нужно что-то менять в наборе? на данный момент мой набор установлен = {ABC}, могу ли я использовать его как set = {ABC} (без трех пробелов, наконец)? - person coder; 11.06.2019
comment
Я не знаю, что такое set, но вы можете проверить SetArrayArgument, который копирует данные в массив под указателем. Не уверен на 100%, что SetArgPointee делает с массивами, вы также можете проверить это. - person Yksisarvinen; 11.06.2019