Код: Выделить всё
class Interface
{
public:
virtual ~Interface = default;
virtual void open(int id) = 0;
virtual void close(int id) = 0;
protected:
// Default other special members here
};
Следующая функция использует интерфейс.
Код: Выделить всё
void actWithId(Interface & interface, int const id)
{
interface.open(id);
interface.close(id);
}
Код: Выделить всё
void act(Interface & interface)
{
actWithId(interface, 1);
actWithId(interface, 2);
actWithId(interface, 3);
}
Код: Выделить всё
void act(Interface & interface)
{
actWithId(interface, 2);
actWithId(interface, 3);
actWithId(interface, 1);
}
- все равно пройти успешно, если я изменю порядок вызовов actWithId()
- разбить при открытии/не по порядку. Например, следующая последовательность вызовов экземпляра Interface должна их нарушить: интерфейс.open(1); интерфейс.открыть(2); интерфейс.закрыть(1); интерфейс.закрыть(2);
Код: Выделить всё
closeВызовы
Чтобы выполнить требование 2, я мог бы использовать объект InSequence следующим образом:
Код: Выделить всё
MockInterface mock;
InSequence const seq;
EXPECT_CALL(mock, open(1));
EXPECT_CALL(mock, close(1));
EXPECT_CALL(mock, open(2));
EXPECT_CALL(mock, close(2));
EXPECT_CALL(mock, open(3));
EXPECT_CALL(mock, close(3));
act(mock);
Вместо этого я мог бы использовать объекты Sequence вот так:
Код: Выделить всё
MockInterface mock;
Sequence const seq1, const seq2, const seq3;
EXPECT_CALL(mock, open(1)).InSequence(seq1);
EXPECT_CALL(mock, close(1)).InSequence(seq1);
EXPECT_CALL(mock, open(2)).InSequence(seq2);
EXPECT_CALL(mock, close(2)).InSequence(seq2);
EXPECT_CALL(mock, open(3)).InSequence(seq3);
EXPECT_CALL(mock, close(3)).InSequence(seq3);
act(mock);
Лучшее, что я могу придумать, — это ввести состояние для отслеживания текущего идентификатора и выдать исключение, если оно не совпадает:
Код: Выделить всё
MockInterface mock;
std::optional currentId;
EXPECT_CALL(mock, open(_)).WillRepeatedly(Invoke([&](int const id)
{
if (currentId.has_value())
{
throw std::runtime_error{ "Calling open() but is not closed" };
}
}));
EXPECT_CALL(mock, close(_)).WillRepeatedly(Invoke([&](int const id)
{
if (!currentId.has_value())
{
throw std::runtime_error{ "Calling close() but is not opened" };
}
if (*currentId != id)
{
throw std::runtime_error{ "Calling close() but was opened with a different id" };
}
}));
Код: Выделить всё
close()
Есть идеи, как добиться этого в рамках GMock? В идеале с помощью одной из операций секвенирования, например .InSequence() или .After().
Подробнее здесь: https://stackoverflow.com/questions/786 ... lock-order