谷歌测试:如何检查调用的全局C(C++)函数

Google test: how to check a global C (C++) function was called

本文关键字:调用 函数 C++ 全局 检查 测试 何检查 谷歌      更新时间:2023-10-16

我正在为嵌入C(或C++)应用程序的脚本语言编写测试用例,其中一个功能是脚本语言从"宿主"程序调用方法。整个项目都使用谷歌测试框架,下面是其中一个测试:

TEST(Functions, ExternalCalling)
{
    SCRIPT_START
    "                                      
    extern void external_callee(int, int); 
    external_callee(1,2);                  
    "
    SCRIPT_END
}
NAP_EXPORTS
void external_callee(nap_int_t a, nap_int_t b)
{
    fprintf(stderr, "na=%"PRINT_d", b=%"PRINT_d"n", a, b);
    if(a != 1 || b != 2) FAIL();
}

不要介意SCRIPT_STARTSCRIPT_END宏,它们只是创建/销毁脚本语言对象(NAP_EXPORTS被定义为extern "C",以便动态库加载器可以解析名称)。

正如你所看到的,脚本定义了一个外部方法(来自主机应用程序),然后调用它。现在我确信该方法被调用了,因为我可以在stderr/输出中看到ab的值,但是的。。。这有一种手动测试的感觉:)我如何使用谷歌测试框架来确保在不需要在屏幕上查看的情况下实际调用了该方法?(我想避免使用黑客式的解决方案,比如使用全局标志…)

您实际想要做的是模拟函数。

看看像googlemock这样的mocking框架。

EXPECT_CALL宏允许您指定调用发生次数(带有参数筛选)。

另请参阅这个SO问题如何创建C蹦床来将C++接口隐藏在C代码后面。

如果您也想得到一个真实的结果,您可能还对invoke函数感兴趣,该函数允许您将参数转发到真实的实现。

谷歌模拟食谱中有适用于上述所有使用模式的食谱。

以下是一些想法,按从最小到最大的顺序排列:

  1. 让函数返回一个字符串,而不是在内部打印它。或者至少还一些东西
  2. external_callee()添加一个(可选)FILE*参数,并在那里写入,而不是对stderr进行硬编码。然后,您的测试工具可以将其连接到一个临时文件或其他更高级的文件
  3. 制作一个全局变量,即要写入的FILE*。默认为stderr,但让测试工具更改它。基本上与前面的想法一样,但不修改签名
  4. 让测试工具将stderr文件描述符作为管道重新打开。调用函数,然后尝试从该管道中读取
  5. 在测试程序中覆盖printf()。是的,你也许可以这样做——试试看!只要用相同的签名自己定义printf(),就应该调用该签名。然后你可以做任何你想做的事