Google имитирует метод ByRef

У меня есть класс, который принимает логическое значение в качестве ссылочного параметра и возвращает целое число:

class Foo
{
  public:
    Bar my_bar;
    virtual int myMethod(bool &my_boolean) = 0;
}

/*...*/

int Foo::myMethod(bool &my_boolean){
  if (my_bar == NULL){
    my_boolean = false;
    return -1;
  }
  else{
    my_boolean = true;
    return 0;
  }

}

И я создал макет для этого класса:

class MockFoo : public Foo
{
   MOCK_METHOD1(myMethod,int(bool &my_boolean));
}

У меня возникли проблемы с тем, как установить ожидания для такого рода функций, потому что мне нужно установить возвращаемое значение и ссылочного параметра на определенные значения, чтобы правильно создать мои модульные тесты. Как я могу справиться с такой функцией с gmock? Я попытался следовать тому, что я считал решением в документации:

using ::testing::SetArgPointee;

class MockMutator : public Mutator {
  public:
  MOCK_METHOD2(Mutate, void(bool mutate, int* value));
  ...
};
  ...

MockMutator mutator;
EXPECT_CALL(mutator, Mutate(true, _))
  .WillOnce(SetArgPointee<1>(5));

Но либо я не понял пример, либо он не применим в данном случае. Кто-нибудь уже сталкивался с такой ситуацией?

Заранее спасибо.


person Rodrigo Vasconcelos    schedule 21.06.2013    source источник
comment
Тогда я не понимаю, в чем твой вопрос. Можешь уточнить свои проблемы? Код кажется мне правильным. Или вы хотите знать, как установить ожидания для эталонного параметра аналогичным образом? ByRef() вполне подойдет для этого.   -  person πάντα ῥεῖ    schedule 22.06.2013
comment
+1 это трудно получить из примеров кулинарной книги.   -  person πάντα ῥεῖ    schedule 22.06.2013


Ответы (1)


Ваш вопрос трудно получить! Примеры из Google издеваются над «поваренной книгой».

Вы хотите повторно использовать реализацию для Foo::myMethod() с вашим фиктивным классом, или вы просто хотите имитировать побочные эффекты (возвращаемое значение и изменение с помощью параметров ref) для конкретных ситуаций вызова?

Мок-класс обычно предназначен для замены/симуляции вашего класса Foo, а не для его прямого наследования или его поведения. Не знаю, будет ли работать то, как вы определяете это поведение «по умолчанию» для чистого метода, но сомневайтесь в этом. Тогда вы можете просто опустить = 0. Лучшим подходом было бы выделить реальное объявление интерфейса, например:

struct IFoo
{
    virtual int myMethod(bool &my_boolean) = 0;
    virtual ~IFoo() {}
};

class Foo : public IFoo
{
    // ...
};

class MockFoo : public IFoo
{
   MOCK_METHOD1(myMethod,int(bool &my_boolean));
};

Если у вас последний случай, вы должны выйти с testing::Return(value) и testing::SetArgReferee<N>(value) (нашел это в очень полезном 'Шпаргалка').

Ваш ожидаемый вызов должен выглядеть следующим образом:

MockFoo foo;

// Expect call to myMethod() return -1 and set the by ref argument to true
EXPECT_CALL(foo, myMethod(_))
  .WillOnce(DoAll(SetArgReferee<0>(true),Return(-1)));

// Expect call to myMethod() return 0 and set the by ref argument to false
EXPECT_CALL(foo, myMethod(_))
  .WillOnce(DoAll(SetArgReferee<0>(false),Return(0)));

Если вы действительно хотите повторно использовать исходную логику классов для myMethod(), посмотрите 'Делегирование вызовов родительскому классу', соотв. 'Делегирование Обращения к реальному объекту '

person πάντα ῥεῖ    schedule 21.06.2013
comment
Извините, @g-makulik, я скопировал и вставил неправильный фрагмент кода, который не имел отношения к этому вопросу. Я исправил его сейчас. - person Rodrigo Vasconcelos; 21.06.2013
comment
Извините также, мне потребовалось немного времени, чтобы понять вашу проблему. ByRef() был ложным путем для этого случая. - person πάντα ῥεῖ; 22.06.2013
comment
@RodrigoVasconcelos Больше не интересно? Это решает ваши проблемы? - person πάντα ῥεῖ; 23.06.2013
comment
Это действительно решило проблему, спасибо @g-makulik! Извините за долгое молчание, моя страна в настоящее время переживает некоторые беспорядки, и это удерживало меня от работы в течение нескольких дней. - person Rodrigo Vasconcelos; 24.06.2013
comment
@РодригоВасконселос Бразилия? - person πάντα ῥεῖ; 24.06.2013
comment
@RodrigoVasconcelos Я не уверен в вашем предложении по редактированию. Действительно ли DoAll() нужен, чтобы заставить его работать? Если да, то я отредактирую ответ. - person πάντα ῥεῖ; 24.06.2013
comment
Да, DoAll() был необходим. - person Rodrigo Vasconcelos; 25.06.2013