I'm not sure what the problem in your case is, but when I run the following code with the version form the git repoitory
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";
}
I get the correct output.
John Doe
I find that I almost always use
mocks.autoExpect = false;
but in this case it doesn't make any difference.
Edit:
If you require more flexibility, you can do something like this:
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"));
which will work in any order of the calls. Alternatively you can also use 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"));