Гугл макет методом 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));

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

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

10

Решение

Ваш вопрос трудно получить! Образцы из 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() посмотри на «Делегирование звонков родительскому классу», соответственно «Делегирование вызовов реальному объекту»

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]