GMock: возврат значения в параметре
Есть интерфейс вида
struct Interface
{
virual int get_param(int id) const = 0;
virual bool set_param(int id, int value) = 0;
virual bool read_block(int id, block_type& value) const = 0;
virual bool write_block(int id, const block_type& value) = 0;
virtual ~Interface() = default;
};
Для него написан Mock
struct InterfaceMock
: public Interface
{
MOCK_METHOD(int, get_param, (int id), (const, override));
MOCK_METHOD(bool, set_param, (int id, int value), (override));
MOCK_METHOD(bool, read_block, (int id, block_type& value), (const, override));
MOCK_METHOD(bool, write_block, (int id, const block_type& value), (override));
};
Так же есть несколько CommandObject, смысл которых получить данные, обработать и вернуть результат.
struct Command
{
virtual void exec(Interface* iface) const = 0;
};
Запнулся на тестировании тех, кто использует метод, возвращающий данные по ссылке:
struct ConcreteCommand
: public Command
{
void exec(Interface* iface) const override
{
// get some params
auto param = iface->get_param(...);
// get data
block_type block;
iface->read_block(..., block);
// process data
....
// set params
iface->set_param(...);
}
}
То есть мне из теста нужно установить данные и затем проверить результат обработки
Как это можно сделать?
UPD_0:
в "Actions / SideEffects" eсть ::testing::SetArgReferee
, но что то не вижу информации о lifetime объектов передаваемых таким способом.
UPD_1:
Способ с SetArgReferee вроде бы работает, но есть опасения: что будет с block
, если вызывать EXPECT_CALL
в цикле?
using ::testing::_;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgReferee;
class CommandTestFixture
: public ::testing
{
//...
}
TEST_F(CommandTestFixture, ConcreteCommand)
{
InterfaceMock mock;
Sequence s;
std::unique_ptr<Interface> = std::make_unique<ConcreteCommand>;
block_type block = ...;
EXPECT_CALL(mock, get_param(...))
.InSequence(s)
.WillRepeatedly(Return(...));
EXPECT_CALL(mock, read_block(..., _))
.InSequence(s)
.WillRepeatedly(SetArgReferee<1>(block));
EXPECT_CALL(mock, set_param(...))
.InSequence(s)
.WillRepeatedly(Return(...));
}