检查函数是否已在gtest中调用 [英] Check if the function has been called in gtest

查看:423
本文介绍了检查函数是否已在gtest中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在gtest框架中,有什么方法可以检查是否已调用函数? (没有gmock,仅使用gtest) 例如:

In gtest framework, is there any way to check whether a function has been called? (without gmock, use gtest only) for example:

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

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

我不在乎功能输入,甚至输出的正确性. 我只想知道功能(例如aa())是否已触发. 有什么解决办法吗?提前非常感谢!

I do not care the function input and even the correctness of the output. I just want to know if the function (e.g. aa()) has been triggered. Is there any solution? Many thanks in advance!

推荐答案

没有gmock,只能使用gtest

without gmock, use gtest only

这是一个非常严格的限制.通常,您无法确定是否调用了函数. Gmock通过生成可记录调用,参数并可以基于运行时参数伪造行为的模拟函数来解决此问题.

That's a very strict restriction. In general, you can't tell if a function was called. Gmock gets around this by generating mock functions that record the calls, arguments and can fake behavior based on runtime parameters.

没有这个,您只有两个选择:

Without this, you only have two options:

这很简单,但很脆弱:如果您知道该功能有明显的副作用,则可以检查一下:

This is straightforward, but brittle: if you know there is a observable side effect of the function, you can check that:

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);
}

您不必将自己限制在函数设置的标志上.日志消息和其他副作用也是可行的.

You don't need to restrict yourself to flags that a function sets. Log messages and other side effects are also workable.

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

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

As mentioned above, this is a brittle solution, because you may be checking a side effect that randomly changes in the future. However, sometimes this is good enough.

这很讨厌,我无法提供完整的示例,因为执行此操作的方法取决于您的编译器和目标.基本上,您指示编译器以一些无操作(不一定为NOP)指令开始生成函数.这使您可以获取函数的地址,将这些指令更改为跳转到某个地方,然后返回.这非常有用,因为您可以调用注册返回地址的函数,并从中知道是否调用了该函数.如果已注册aa()的返回地址,则称它为

This is nasty and I can't provide a complete example because the way to do this depends on your compiler and target. Basically, you instruct the compiler to generate the functions starting with a few no-op (not necessarily NOP) instructions. This allows you to take the address of the function, change these instructions to jump somewhere and then back. This is very useful because you can call a function that registers the return address and from that you can tell if a function was called or not. It was called iif the return address of aa() is registered.

您将需要特定于操作系统的调用来热修补您的代码,并且需要一些有关正在运行的CPU指令的知识.您显然失去了可移植性.我也不知道您的要求,但这可能不值得麻烦.

You will need OS-specific calls to hotpatch your code and some knowledge of the CPU instructions you are running on. You obviously lose portability. I also don't know your requirements, but this probably isn't worth the trouble.

总而言之,如果您想停留在标准范围之内,那么最好的选择就是gmock.虚函数是动态分配的标准方法(如果您正在热分配映像,这将是您要做的事情).

All in all, your best bet is gmock, if you want to stay in the boundaries of the standard. Virtual functions are the standard way of dynamic dispatch (which is what you would do if you were hotpatching your image).

这篇关于检查函数是否已在gtest中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆