21

C で記述されたレガシー プロジェクトを維持していますが、C++ コンパイラで実行することはできません。ただし、コードはクロス コンパイルされているため、ホスト環境で単体テストなどを実行することは可能です。したがって、C++ ホスト コンパイラと連携して google-test と google-mock を使用することも可能です。

google-mock には、実際の実装を呼び出して呼び出しの期待値を設定するなどのテストに使用したくなるような特定の機能があります。

それらをCコードで使用できるようにしたいと思います。vtables を使用せずに google-mock を使用することは実際に可能であることがわかりますが、テンプレートが必要です。

Googleモックで裸のC関数をモックする方法はありますか?

編集

私は基本的に Google モックを使用する必要がありましたが、このスレッドを読む他のすべての人は私よりも柔軟性が高いと思います。

4

4 に答える 4

15

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));
于 2013-10-24T07:34:31.577 に答える
3

Google Mock FAQ からのように:

私のコードは静的/グローバル関数を呼び出します。嘲笑してもいいですか?
できますが、いくつかの変更を加える必要があります。

一般に、静的関数をモックする必要がある場合は、モジュールが緊密に結合されている (柔軟性が低く、再利用性が低く、テストしにくいなど) ことを示しています。おそらく、小さなインターフェイスを定義し、そのインターフェイスを介して関数を呼び出す方が良いでしょう。これは簡単にモックできます。最初は少し手間がかかりますが、通常はすぐに元が取れます。

This Google Testing Blog postはそれを見事に述べています。見てみな。

于 2013-10-23T21:43:29.683 に答える
2

あなたの質問は具体的にGoogle Mockに言及していますが、そのフレームワークを使用する他の理由は述べていません。もう1つの答えは、不必要に邪魔に見える回避策を使用することを提案しています。

したがって、弱いエイリアスなどを使用しなくてもうまく機能する別の提案をすることが許されることを願っています.

私は CppUTest ( https://cpputest.github.io/ ) をモックを使用した単体テストに使用し、いくつかの大規模な主に C プロジェクト (いくつかの C++) で成功しました。モッキングは、上記の種類の策略に頼る必要なく機能します。

残念ながら、プロジェクトのドキュメントは少し貧弱で、書籍 (PDF として配布されているものもある) にあるより良い (少しアジャイルな教義であれば) 情報と例があります。"Test Driven Development for Embedded C" - James W Greening (ISBN-13: 978-1-934356-62-3)

于 2016-11-21T11:41:22.563 に答える