我正在维护一个用C编写的遗留项目,用C编译器运行它是不可行的。由于代码是交叉编译的,因此可以在主机环境中运行单元测试或类似测试。因此,也可以与C主机编译器接口,并使用google-test和google-mock。
google-mock的某些功能似乎非常适合用于调用真实的实现和设置调用期望的测试。
我希望能够在C代码中使用它们。我可以看到,使用google-mock而不使用vtables确实是可能的,但它需要模板。
有没有办法用google mock来模拟裸C函数?
编辑:
我基本上不得不使用谷歌模拟,我认为,虽然其他人谁会读这个线程有更好的灵活性比我。
4条答案
按热度按时间fnx2tebb1#
我找到了一种在google-mock中模拟裸C函数的方法。
解决方案是将
foobar
声明为Map到foobarImpl
的弱别名。在生产代码中,您不实现foobar()
,而对于单元测试,您提供了一个调用静态模拟对象的实现。这个解决方案是特定于GCC的,但也有其他编译器/链接器提供弱别名。
void foobar();
重命名为void foobarImpl();
foobar
中添加一个属性,如下所示:void foobar() __attribute__((weak, alias("foobarImpl") ));
因此:
成为
和
这将告诉gnu链接器在没有名为
foobar()
的符号时将foobar()
的调用链接到foobarImpl()
。然后添加测试代码
如果这段代码被编译和链接,它将用mock调用替换
foobar
。如果你真想调用foobar()
,你仍然可以添加一个默认调用。cig3rfwq2#
Google Mock FAQ:
我的代码调用静态/全局函数。我能嘲笑它吗?
你可以,但你需要做一些改变。
一般来说,如果你发现自己需要模拟一个静态函数,这表明你的模块耦合得太紧了(灵活性、可重用性、可测试性等都比较差)。最好定义一个小接口,并通过该接口调用函数,这样就可以很容易地模仿它。这是一个有点工作开始,但通常支付本身很快。
谷歌测试博客post说得很好。看看吧
ecbunoof3#
你的问题特别提到了Google Mock,但没有说明使用该框架的任何其他原因。另一个答案建议使用一个似乎不必要的侵入性的解决方案。
因此,我希望我可以提出一个替代的建议,它可以很好地工作,而不必使用弱别名等。
我使用CppUTest(https://cpputest.github.io/)进行单元测试,并在几个大型的主要C项目(一些C++)上成功地进行了模拟。嘲笑的工作,而不必诉诸任何托辞上述排序。
不幸的是,项目文档有点薄弱,一些更好的(如果有点敏捷教条)信息和例子在书中(也被视为PDF格式)“嵌入式C的测试驱动开发”- James W Greening(ISBN-13:电话:978-1-934356-62-3)
ux6nzvsh4#
我知道这是一个超级老的线程,但我希望我可以让别人的生活更容易,如果和当他们遇到这个问题。
您可以使用Mimicc轻松地自动生成与GoogleTest兼容的C函数的模拟。找到任何声明了你想要模拟的函数的头文件,将它们“编译”成模拟实现对象文件,并将它们链接到你的测试二进制文件中,包括Google Test用户指南中专门描述的
mock_fatal()
和mock_failure()
函数的定义。您必须使用Mimicc API来与Mimicc生成的模拟(即它不使用GoogleMock的API来设置期望值等),但它们可以与GoogleMock生成的模拟轻松共存。更具体地说,假设您有一个C头文件
foo.h
,它声明了一些您想要模拟的函数。举例来说:您可以通过编译
foo.h
与用于编译附带的生产foo.c
的所有相同CFLAGS
来创建这些的模拟:要在测试中使用它,请使用
foo-mock.h
中声明的API设置期望和返回,如上面的命令行调用所示。包括mock_fatal()
和mock_failure()
的Google Test实现。虽然这看起来很多,但一旦设置了管道,您就可以自动模拟任何C或C++代码,而无需实际编写或维护额外的模拟代码,您只需专注于测试。从长远来看会容易一些。