在gtest框架中,有没有办法检查函数是否被调用? (没有gmock,只能使用gtest) 例如:
class a
{
public:
void dd() {...};
void cc() {...};
void bb() {...};
void aa()
{
bb(cc(dd()));
}
};
void main ()
{
a dut;
dut.aa();
}
我不关心功能输入甚至输出的正确性。 我只是想知道函数(例如aa())是否已被触发。 有什么解决方案吗?非常感谢提前!
答案 0 :(得分:3)
没有gmock,只使用gtest
这是一个非常严格的限制。通常,您无法判断是否调用了函数。 Gmock通过生成模拟函数来解决这个问题,这些函数记录调用,参数并且可以基于运行时参数伪造行为。
如果没有这个,你只有两个选择:
这很简单,但很脆弱:如果您知道该功能有可观察到的副作用,您可以检查:
class a
{
public:
a() : aa_flag(false) {}
void aa()
{
aa_flag = true;
}
bool aa_flag;
};
TEST(FuncCalled, CheckSideEffectFlag)
{
a dut;
dut.aa();
EXPECT_TRUE(dut.aa_flag);
}
您不需要将自己限制为函数设置的标志。日志消息和其他副作用也是可行的。
class a
{
public:
a() : aa_flag(false) {}
void aa()
{
LOG_INFO("aa called");
}
bool aa_flag;
};
TEST(FuncCalled, CheckSideEffectLog)
{
a dut;
dut.aa();
EXPECT_TRUE(LogContains("aa called"));
}
如上所述,这是一个脆弱的解决方案,因为您可能正在检查将来随机变化的副作用。但是,有时这已经足够了。
这很讨厌,我无法提供完整的示例,因为这样做的方式取决于您的编译器和目标。基本上,您指示编译器生成以少数无操作(不一定是NOP)指令开头的函数。这允许您获取函数的地址,更改这些指令以跳转到某处然后返回。这非常有用,因为您可以调用一个注册返回地址的函数,从中可以判断函数是否被调用。如果注册aa()
的返回地址,则称为iif。
您将需要特定于操作系统的调用来编写代码以及您正在运行的CPU指令的一些知识。你显然会失去便携性。我也不了解你的要求,但这可能不值得。
总而言之,如果你想留在标准的边界,你最好的选择是gmock。虚函数是动态调度的标准方法(如果您正在对图像进行热修补,则会执行此操作)。