Чтобы реализовать последовательность вызовов в Google Mock, где метод `set_control` должен вызываться только после вызовов `get_control` и `get_register`, в то время как сами методы `get_control` и `get_register` могут вызываться в произвольном порядке, вы можете использовать `InSequence` только для метода `set_control`. При этом для методов `get_control` и `get_register` последовательность вызовов не будет обязательной.
Вот пример кода, который решает вашу задачу:
```cpp
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using ::testing::_;
using ::testing::Return;
using ::testing::SetArgReferee;
class MockVM {
public:
MOCK_METHOD(void, set_control, (int, int), ());
MOCK_METHOD(void, get_control, (int, int&), ());
MOCK_METHOD(int, get_register, (int), ());
};
class MyClass {
public:
void exec(MockVM* vm, int* code) {
int control_value;
int reg_value = vm->get_register(1);
vm->get_control(2, control_value);
int result = reg_value + control_value; // example computation
vm->set_control(2, result);
}
};
TEST(MyClassTest, TestCallbackOrder) {
MockVM mockVm;
MyClass impl;
int csr_id = 2;
int src = 1;
int csr_val = 10;
int src_val = 5;
int expected_csr_value = csr_val + src_val;
// Create a sequence for set_control
::testing::Sequence seq;
EXPECT_CALL(mockVm, get_control(csr_id, _))
.WillOnce(SetArgReferee<1>(csr_val));
EXPECT_CALL(mockVm, get_register(src))
.WillOnce(Return(src_val));
// Ensure that set_control is called after the other calls
EXPECT_CALL(mockVm, set_control(csr_id, expected_csr_value))
.InSequence(seq);
// Call the method under test
int code; // Example usage, may need to change based on your implementation
impl.exec(&mockVm, &code);
}
```
В этом примере:
- Мы определили порядок вызовов так, чтобы `set_control` должен вызываться в последовательности (используя `InSequence`), но методы `get_control` и `get_register` могут вызываться в любом порядке.
- Мы назначаем ожидания для `get_control` и `get_register` без установки их в последовательность. Это приводит к тому, что они могут быть вызваны в любом порядке перед вызовом `set_control`.
Таким образом, вы обеспечиваете, что `set_control` вызывается только после выполнения обоих предыдущих методов, что соответствует требованиям вашего теста.