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

3

我正在为嵌入在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/output 上看到 ab 的值,但是...这感觉像是手动测试 :) 如何使用 Google 测试框架确保该方法实际被调用,而无需查看屏幕?(我想避免 hackish 解决方案,比如使用全局标志...)

你能否将 external_callee 的签名更改为包括 FILE* 而不是硬编码的 stderr - John Zwinck
@JohnZwinck 不是很对,因为脚本语言类型(int)和 C 类型(nap_int_t)之间必须匹配。 - Ferenc Deak
如果是纯C,使用Google Mocks可能会变得棘手。请查看https://cmocka.org/。 - Mawg says reinstate Monica
2个回答

3
你实际想要做的是模拟函数。
看看像google-mock这样的模拟框架。 EXPECT_CALL宏允许您指定调用发生的次数(带有参数过滤)。
还可以参考This SO Question如何创建C trampolins以在C代码后面隐藏C++接口。
如果您还想获得真正的结果,您可能会对invoke函数感兴趣,该函数允许您将参数转发到真正的实现中。 google mock cookbook提供了上述所有使用模式的示例。

1
以下是从不那么阴险到最阴险的一些想法:
1. 使您的函数返回字符串而不是在内部打印它。或者至少返回一些东西。 2. 向external_callee()添加一个(可选的)FILE*参数,并在那里写入,而不是硬编码stderr。然后,您的测试工具可以将其连接到临时文件或更高级的内容。 3. 创建一个全局变量,它是要写入的FILE*。默认为stderr,但让测试工具更改它。基本上就像前一个想法,但没有修改签名。 4. 让您的测试工具将stderr文件描述符重新打开为管道。调用该函数,然后尝试从该管道读取。 5. 在测试程序中覆盖printf()。是的,您可能可以做到这一点 - 试试吧!只需使用相同的签名自己定义printf(),就会调用那个。然后您可以随心所欲地做任何事情。

好主意,但您没有包含正确/惯用/传统的内容:模拟external_callee - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接