0

次のコードを持つクラスがあるとします

void MessageBuilder::Init(DBusMessage* pMsg)
{
    if (NULL != m_pMsg)
    {
        ::dbus_message_unref(m_pMsg);
    }
    // m_pMsg is a private data member
    m_pMsg = pMsg;
    ::dbus_message_iter_init_append(m_pMsg, &m_objArgs);
}

DBUS 呼び出しは名前空間にあるため、:: (私は信じています)。::dbus_* 呼び出しをモック/スタブ化する方法を誰かが提案できますか?

4

1 に答える 1

3

GoogleMockを使用すると、クラスの仮想メソッドを偽造できます。しかし、:: dbus_ *関数はどのクラスのメンバーでもありません(そうです、それらは名前空間にあります:グローバル名前空間)。したがって、GoogleMockを(直接)使用することはできません。

EmbeddedCのテスト駆動型開発のJamesW.Grenningは、問題に対するいくつかの解決策を提案しています。

  1. リンク時の置換:テストコードを:: dbus_ *関数コードを含む元のライブラリにリンクせず、代わりにテストプロジェクトに新しいC / CPPファイルを作成します。これにより、によって使用されるすべての::dbus_*関数の偽物が実装されます。テスト中のコンポーネント。また、テスト対象のコンポーネントをテストプロジェクトに追加して、リンカーが偽物への::dbus_*呼び出しを自動的に解決するようにします。
  2. 関数ポインタの置換:テスト対象のコンポーネントで:: dbus_ *関数を直接使用する代わりに、関数ポインタを使用します。関数ポインタは、本番コードでは:: dbus_ *関数に、テストコードでは偽の関数に初期化されます。
  3. プリプロセッサの置換#define名前を上書きするために使用します。たとえば#define dbus_message_unref(p) fake_dbus_message_unref(p)、テスト対象のコンポーネントが独自の偽の関数を呼び出すようにしますfake_dbus_message_unref()。このアプローチでは、テスト対象のコンポーネントをテストプロジェクトに追加する必要があります。

提案1が実行可能であり、リンクの問題が発生しない場合、提案2よりも作業がはるかに少なくなります。提案3の安っぽい部分は、テスト対象のコンポーネントのコードを実際に変更(!)することです。 3.提案1から離れてください。推奨される方法です。

もう1つの方法は、:: dbus_*関数の周りの仮想メソッドでC++ラッパークラスを使用することです。これにより、GoogleMockなどのモックツールを使用してそれらを偽造できます。そのようなラッパーを書くことはおそらくかなりの努力を意味するでしょう。ショートカットとして、DBUS C ++ラッパーライブラリを検索できます。運が良ければ、モック可能なものを見つけることができます。

于 2012-12-07T14:18:51.910 に答える