google-mock で裸の C 関数をモックできる方法を見つけました。
foobar
解決策は、 にマップされる弱いエイリアスであると宣言することfoobarImpl
です。本番コードでは実装せずfoobar()
、単体テストでは静的モック オブジェクトを呼び出す実装を提供します。
このソリューションは GCC 固有のものですが、弱いエイリアシングを提供する他のコンパイラ/リンカーがあります。
- 関数の名前
void foobar();
をvoid foobarImpl();
foobar
次のような属性を関数に追加します。void foobar() __attribute__((weak, alias("foobarImpl") ));
- 弱いエイリアスを持たない場合は、プリプロセッサ ディレクティブを使用して属性から弱いエイリアスを削除します。
したがって:
#pragma once
void foobar();
になる
// header.h
#pragma once
void foobar();
void foobarImpl(); // real implementation
と
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
これは、呼び出されたシンボルがない場合は常にの呼び出しfoobar()
をリンクするように gnu リンカに指示します。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));