Можно ли повторно использовать макет для нескольких ожидаемых вызовов с разными возвращаемыми значениями в Гиппопотамах?

Я пользуюсь Hippo Mocks с большим успехом, но у меня есть ситуация, которую я не могу понять, как правильно настроить. Тестируемый код выглядит примерно так:

auto firstName = record.at("firstName").getValue();
auto lastName = record.at("lastName").getValue();

куда IRecord::at() возвращает IColumn&, который имеет чисто виртуальный getValue() метод. Я пытаюсь протестировать мой код с поддельными версиями Irecord а также IColumn:

auto mockRec = mocks.InterfaceMock<IRecord>();
auto mockCol = mocks.InterfaceMock<IColumn>();

Я могу настроить ожидания для firstName просто хорошо:

mocks.OnCall(mockRec, IRecord::at).With("firstName").Return(std::ref(*mockCol));
mocks.OnCall(mockCol, IColumn::getValue).Return(std::string("John")));

Но я хотел бы повторно использовать IColumn издеваться над следующим ожиданием lastName,

mocks.OnCall(mockRec, IRecord::at).With("lastName").Return(std::ref(*mockCol));
mocks.OnCall(mockCol, IColumn::getValue).Return(std::string("Doe")));

Но когда я запускаю это, Hippo Mocks возвращает «John» для обоих getValue() звонки.

Следуя вместе с руководство, Я попытался ограничить порядок вызовов «firstName» и «lastName»:

auto& firstCall = mocks.OnCall(mockRec, IRecord::at).With("firstName").Return(std::ref(*mockCol));
mocks.OnCall(mockCol, IColumn::getValue).After(firstCall).Return(std::string("John")));

auto& lastCall = mocks.OnCall(mockRec, IRecord::at).With("lastName").Return(std::ref(*mockCol));
mocks.OnCall(mockCol, IColumn::getValue).After(lastCall).Return(std::string("Doe")));

Но я все еще получаю «Джона» для обоих getValue() звонки.

Q: Можно ли повторно использовать IColumn интерфейс и сказать Hippo Mocks возвращать разные значения с каждым getValue() звоните, как мне нужно, или я застрял, создавая отдельный IColumn макет для каждого параметра? Примечание: моя фактическая реализация будет иметь более двух параметров, поэтому повторное использование IColumn макет уменьшает множество настроек для каждого модульного теста.

1

Решение

Я не уверен, что проблема в вашем случае, но когда я запускаю следующий код с версия из репозитория git

struct IColumn {
virtual std::string getValue() = 0;
};

struct IRecord {
virtual IColumn& at( std::string ) = 0;
};

void main()
{
MockRepository mocks;

auto mockRec = mocks.Mock<IRecord>();
auto mockCol = mocks.Mock<IColumn>();

auto& firstCall = mocks.OnCall(mockRec, IRecord::at).With("firstName").Return(std::ref(*mockCol));
mocks.OnCall(mockCol, IColumn::getValue).After(firstCall).Return(std::string("John"));

auto& lastCall = mocks.OnCall(mockRec, IRecord::at).With("lastName").Return(std::ref(*mockCol));
mocks.OnCall(mockCol, IColumn::getValue).After(lastCall).Return(std::string("Doe"));

std::cout << mockRec->at("firstName").getValue() << " "<< mockRec->at("lastName").getValue() << "\n";
}

Я получаю правильный вывод.

John Doe

Я считаю, что я почти всегда использую

mocks.autoExpect = false;

но в этом случае это не имеет никакого значения.

Редактировать:

Если вам требуется больше гибкости, вы можете сделать что-то вроде этого:

std::vector<IColumn*> cols;

cols.push_back( mocks.Mock<IColumn>() );
cols.push_back( mocks.Mock<IColumn>() );

mocks.OnCall(mockRec, IRecord::at).With("firstName")
.Return(std::ref(*cols[0]));
mocks.OnCall(mockRec, IRecord::at).With("lastName")
.Return(std::ref(*cols[1]));

mocks.OnCall(cols[0], IColumn::getValue)
.Return(std::string("John"));
mocks.OnCall(cols[1], IColumn::getValue)
.Return(std::string("Doe"));

который будет работать в любом порядке звонков. В качестве альтернативы вы также можете использовать Do

std::map<std::string, IColumn*> map;

map["firstName"] = mocks.Mock<IColumn>();
map["lastName"] = mocks.Mock<IColumn>();

mocks.OnCall(mockRec, IRecord::at)
.Do( [&map]( std::string& key){ return std::ref(*map[key]); } );

mocks.OnCall(map["firstName"], IColumn::getValue)
.Return(std::string("John"));
mocks.OnCall(map["lastName"], IColumn::getValue)
.Return(std::string("Doe"));
2

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

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

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