Вызвать метод на реальном объекте с помощью gmock c ++ - PullRequest
0 голосов
/ 07 февраля 2020

Я смоделировал функцию из объекта с помощью gmock. Теперь я хочу, чтобы при каждом вызове этой функции она вызывала функцию объекта A, передавая Param в качестве параметра. Ниже вы можете найти фрагмент кода

//class I want to call
class A {
public: 
    void func1(const Param& p) {cout<<p.name_<<endl;};
}

class Param {
public:
    string name_;
}


class IMock {
public:
    virtual void func2(int x) = 0;
}

class Mock : public IMock{
public: 
    MOCK_METHOD(void, func2, (int x), (override));
}

Test:

A a;
Param param;
Mock mock;
EXPECT_CALL(mock, func2(_))
    .WillOnce(
        testing::WithArg<param>(testing::Invoke(&a, a.func1)));

Но у меня есть следующие ошибки компиляции:

  • The значение параметра не может быть использовано в константном выражении

  • Неправильное использование не статически c функции-члена virtual void A :: func1 (const Param &)

Есть идеи?

РЕДАКТИРОВАТЬ 1

После ответа @pptaszni новый код теста:

TEST(Test_case, test_flow) {
    A a;
    Param param;
    Mock mock;
    ON_CALL(mock, func2(_)).WillDefault(testing::Invoke(
        [&a, &param]() { a.func1(param); })));
    mock.func2(23);
}

Но теперь компилятор говорит:

нет соответствующей функции для вызова тестирования :: internal :: OnCallSpe c :: WillByDefault (std :: decay> :: type) [& a, & param] () {a.func1 (пары); })); Примечание: кандидат: тестирование :: internal :: OnCallSpec & testing :: internal :: OnCallSpe c :: WillByDefault (постоянное тестирование :: Action &) [с F = void (int)] OnCallSpec & WillByDefault (const Действие и действие) {^ ~ ~~~~~~~~~~~ примечание: неизвестное преобразование для аргумента 1 из 'std :: decay> :: type {aka Test_case_test_flow :: TestBody () ::}' в 'const testing :: Action &'

Я использую последнюю версию googletet avaialble на GitHub (1.10)

1 Ответ

1 голос
/ 07 февраля 2020

Я всегда использую лямбда-выражение внутри Invoke, потому что ИМХО это самый гибкий подход.

TEST(xxx, yyy)
{
  A a;
  Param param;
  Mock mock;
  EXPECT_CALL(mock, func2())
    .WillOnce(Invoke([&a, &param]()
    {
      a.func1(param);
    }));
  mock.func2();
}

Если вы не хотите передавать ссылки на a и param, вы может создать тестовое устройство, объявить их как поля защищенного устройства и передать this в блок лямбда-захвата.

Обратите внимание, что лямбда-выражение должно во многом соответствовать вашей Mock::func2. В этом примере он принимает 0 аргументов.

Кроме того, вы писали

каждый раз, когда вызывается эта функция

В этом случае лучше использовать

ON_CALL(mock, mocked_method(/*params*/)).WillByDefault(Invoke(/*rest of the code*/));

особенно если у вас есть тестовое устройство и вы можете настроить это действие по умолчанию в конструкторе вашего устройства (или SetUp).

...