我找到了一种能够在 google-mock 中模拟裸 C 函数的方法。
解决方案是声明foobar
是映射到的弱别名foobarImpl
。在生产代码中您没有实现foobar()
对于单元测试,您提供一个调用静态模拟对象的实现。
该解决方案是 GCC 特定的,但还有其他提供弱别名的编译器/链接器。
- 重命名函数
void foobar();
to void foobarImpl();
- 向函数添加属性
foobar
like: void foobar() __attribute__((weak, alias("foobarImpl") ));
- 如果您想要一个非弱别名,请使用预处理器指令从属性中删除弱别名。
Hence:
#pragma once
void foobar();
becomes
// header.h
#pragma once
void foobar();
void foobarImpl(); // real implementation
and
extern "C" {
#include "header.h"
}
// code.c
void foobarImpl() {
/* do sth */
}
void foobar() __attribute__(( weak, alias ("foobarImpl") )); // declare foobar to be a weak alias of foobarImpl
这将告诉 gnu 链接器链接调用foobar()
with foobarImpl()
每当没有符号调用时foobar()
然后添加测试代码
struct FooInterface {
virtual ~FooInterface() {}
virtual void invokeFoo() const { }
};
class MockFoo : public FooInterface {
public:
MOCK_CONST_METHOD0(invokeFoo, void());
}
struct RealFoo : public FooInterface {
virtual ~RealFoo() {}
virtual void invokeFoo() const { foobarImpl(); }
};
MockFoo mockFoo;
RealFoo realFoo;
void foobar() {
mockFoo.invokeFoo();
}
如果此代码被编译并链接,它将替换foobar
与模拟通话。
如果你真的想打电话foobar()
您仍然可以添加默认调用。
ON_CALL(mockFoo, invokeFoo())
.WillByDefault(Invoke(&realFoo,&RealFoo::invokeFoo));