我正在尝试使用 Google Test 检查函数调用(模拟方法)的顺序,但是当函数调用循环发生时我遇到了问题。在以下示例中,模拟
DummyClass
以测试DummyUser
。在函数anyFunction
中,方法func_a
、func_b
、func_c
和func_d
在函数的不同位置被多次调用。虽然顺序是确定的,但调用次数在编译时并不确定。我想检查一下顺序,并且他们至少被调用了一次。
class DummyUser {
private:
DummyClass &dc;
public:
DummyUser(DummyClass &dc) : dc(dc) {}
bool anyFunction(int b) {
dc.func_b();
int random_num = getRandomNumber();
for(int i = 0; i < random_num; ++i) {
dc.func_c();
}
dc.func_a();
for(int i = 0; i < dc.func_b(); ++i) {
dc.func_c();
}
dc.func_d();
dc.func_b();
return true;
}
};
我通过为在多个位置调用的每个函数设置一个
Sequence
变量和一个“主”Sequence
变量来解决这个问题:
TEST(Mock, Test) {
Sequence b;
Sequence c;
Sequence main;
MockDummyClass mdc;
DummyUser du(mdc);
ON_CALL(mdc, func_a()).WillByDefault(Return(1));
ON_CALL(mdc, func_b()).WillByDefault(Return(2));
ON_CALL(mdc, func_c()).WillByDefault(Return(3));
ON_CALL(mdc, func_d()).WillByDefault(Return(4));
EXPECT_CALL(mdc, func_b).Times(1).InSequence(b, main);
EXPECT_CALL(mdc, func_c).Times(AtLeast(1)).InSequence(c, main);
EXPECT_CALL(mdc, func_a).Times(1).InSequence(main);
EXPECT_CALL(mdc, func_b).Times(AtLeast(1)).InSequence(b, main);
EXPECT_CALL(mdc, func_c).Times(AtLeast(1)).InSequence(c);
EXPECT_CALL(mdc, func_d).Times(1).InSequence(b, main);
EXPECT_CALL(mdc, func_b).Times(1).InSequence(b, main);
du.anyFunction(3);
}
但是,我对这个解决方案不是 100% 满意。有更好的方法吗?
期望在创建时处于活动状态,并在稍后必须发生的调用发生时变为不活动(也称为退休)。
单个序列的测试用例效果很好:
TEST(Mock, Test) {
MockDummyClass mdc;
DummyUser du(mdc);
ON_CALL(mdc, func_a()).WillByDefault(Return(1));
ON_CALL(mdc, func_b()).WillByDefault(Return(2));
ON_CALL(mdc, func_c()).WillByDefault(Return(3));
ON_CALL(mdc, func_d()).WillByDefault(Return(4));
InSequence main;
EXPECT_CALL(mdc, func_b);
EXPECT_CALL(mdc, func_c).Times(AtLeast(1)); // When func_c() is called, the expectation of func_b() above retires.
EXPECT_CALL(mdc, func_a); // When func_a() is called, the expectation of func_c() above retires.
EXPECT_CALL(mdc, func_b).Times(AtLeast(1));
EXPECT_CALL(mdc, func_c).Times(AtLeast(1));
EXPECT_CALL(mdc, func_d);
EXPECT_CALL(mdc, func_b);
du.anyFunction(3);
}