检查是否已在gtest中调用该函数

时间:2016-05-10 09:00:33

标签: c++ googletest

在gtest框架中,有没有办法检查函数是否被调用? (没有gmock,只能使用gtest) 例如:

class a
{
    public: 
    void dd() {...};
    void cc() {...};
    void bb() {...};
    void aa()
    {
        bb(cc(dd()));
    }
};

void main ()
{
    a dut;
    dut.aa();
}

我不关心功能输入甚至输出的正确性。 我只是想知道函数(例如aa())是否已被触发。 有什么解决方案吗?非常感谢提前!

1 个答案:

答案 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"));
}

如上所述,这是一个脆弱的解决方案,因为您可能正在检查将来随机变化的副作用。但是,有时这已经足够了。

Hotpatch跟踪调用的函数

这很讨厌,我无法提供完整的示例,因为这样做的方式取决于您的编译器和目标。基本上,您指示编译器生成以少数无操作(不一定是NOP)指令开头的函数。这允许您获取函数的地址,更改这些指令以跳转到某处然后返回。这非常有用,因为您可以调用一个注册返回地址的函数,从中可以判断函数是否被调用。如果注册aa()的返回地址,则称为iif。

您将需要特定于操作系统的调用来编写代码以及您正在运行的CPU指令的一些知识。你显然会失去便携性。我也不了解你的要求,但这可能不值得。

总而言之,如果你想留在标准的边界,你最好的选择是gmock。虚函数是动态调度的标准方法(如果您正在对图像进行热修补,则会执行此操作)。