Подтвердить что ты не робот

Настройки по умолчанию gmock/ON_CALL против EXPECT_CALL

Я не понимаю разницы ON_CALL и EXPECT_CALL при использовании укажите действие по умолчанию.

До сих пор я заметил/узнал, что есть два способа настроить действие макета по умолчанию:

ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01));

или

EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01));

Может ли мне объяснить мне:

  • Разница между двумя методами
  • Взлеты и падения каждого
  • Когда это целесообразно использовать (какая настройка...)
4b9b3361

Ответ 1

Существуют тонкие, но существенные различия между двумя утверждениями. EXPECT_CALL устанавливает ожидания при макетных вызовах. Запись

EXPECT_CALL(mock, methodX(_)).WillRepeatedly(do_action);

сообщает gMock, что methodX может быть вызван на mock любое число раз с любыми аргументами, а когда это будет, mock выполнит do_action. С другой стороны,

ON_CALL(mock, methodX(_)).WillByDefault(do_action);

сообщает gMock, что всякий раз, когда methodX вызывается на mock, он должен выполнять do_action. Эта функция полезна в сценарии, в котором вы должны написать много ожиданий от своего макета, и большинство/все они должны указать одно и то же действие, особенно если оно сложное. Вы можете указать это действие в ON_CALL, а затем написать EXPECT_CALL без указания действия явно. Например.

ON_CALL(mock, Sign(Eq(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("argument is zero"), Return(0)));
ON_CALL(mock, Sign(Gt(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("argument is positive"), Return(1)));
ON_CALL(mock, Sign(Lt(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("argument is negative"), Return(-1)));

Теперь, если вам нужно написать много EXPECT_CALL s, вам не нужно mock указывать поведение каждый раз:

EXPECT_CALL(mock, Sign(-4, _));
EXPECT_CALL(mock, Sign(0, _));
EXPECT_CALL(mock, Sign(1, _)).Times(2);
EXPECT_CALL(mock, Sign(2, _));
EXPECT_CALL(mock, Sign(3, _));
EXPECT_CALL(mock, Sign(5, _));

В другом примере, предполагая, что Sign возвращает int, если вы пишете

ON_CALL(mock, Sign(Gt(0), _)).WillByDefault(Return(1));
EXPECT_CALL(mock, Sign(10, _));

вызов mock.Sign(10) вернет 1, поскольку ON_CALL предоставляет поведение по умолчанию для вызова, указанного EXPECT_CALL. Но если вы пишете

EXPECT_CALL(mock, Sign(Gt(0), _).WillRepeatedly(Return(1));
EXPECT_CALL(mock, Sign(10, _));

вызов mock.Sign(10, p) вернет 0. Он будет сопоставлен со вторым ожиданием. Это ожидание не указывает никаких явных действий, и gMock будет генерировать для него действие по умолчанию. Это действие по умолчанию - вернуть значение по умолчанию возвращаемого типа, которое равно 0 для int. В этом случае первое ожидание будет полностью проигнорировано.

Ответ 2

ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01));
EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01));

Как вы сказали, эти две строки делают то же самое, поэтому никаких различий вообще нет. Используйте любой способ для установки действия по умолчанию, как вам удобно.

Однако существует логическая разница:

  • ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01)); означает, что метод может быть вызван, и если это произойдет, каждый вызов вернет 0x01
  • EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01)); означает, что ожидается, что метод будет вызван, и каждый вызов вернет 0x01

Кстати, есть Установка действий по умолчанию в их чит-листе, в котором говорится:

Чтобы настроить действие по умолчанию для определенного метода, используйте ON_CALL():

ON_CALL(mock_object, method(matchers))
    .With(multi_argument_matcher)  ?
    .WillByDefault(action);