web-dev-qa-db-ja.com

Googleは、スマートポインターの戻り値の型を持つメソッドをモックできますか?

スマートポインタを返すファクトリがあります。使用しているスマートポインターに関係なく、Google Mockでファクトリメソッドをモックできません。

モックオブジェクトは、すべてのメソッドが仮想である純粋な抽象インターフェースの実装です。私にはプロトタイプがあります:

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>());

そして私は得る:

"...gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'"

スマートポインターでポイントされる型が定義されます。

そして、プライベートと宣言されたコンストラクタの1つにアクセスしようとしているのですが、その理由がわかりません。これがstd :: auto_ptrの場合、エラーはコピーコンストラクターがないことを示し、混乱を招きました。

とにかく、スマートポインターを返すメソッドをモックする方法はありますか?それとも工場を建設するより良い方法はありますか?私の唯一の解決策は、生のポインタ(blech ...)を返すことですか?

私の環境はVisual Studio 2010 UltimateとWindows 7です。CLIを使用していません。

46

非(const)コピー可能な関数引数とretun値に関するGoogleモックフレームワークの問題の実行可能な回避策は、プロキシモックメソッドを使用することです。

次のインターフェース定義があるとします(このように_std::unique_ptr_を使用するのが良いスタイルである場合、多かれ少なかれ哲学的な質問のように思われますが、私は個人的に所有権の譲渡を強制します)。

_class IFooInterface {
public:
    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0;
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0;
    virtual ~IFooInterface() {}
};
_

適切なモッククラスは次のように定義できます。

_class FooInterfaceMock
: public IFooInterface {
public:
    FooInterfaceMock() {}
    virtual ~FooInterfaceMock() {}

    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) {
        nonCopyableParamProxy(uPtr.get());
    }
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() {
        return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy());
    }


    MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*));
    MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing* ());
};
_

nonCopyableReturnProxy()メソッドの構成(実行されたアクション)がNULLまたはヒープに動的に割り当てられたインスタンスを返すように注意する必要があります。


google-mock user forum thread がこのトピックについて議論していて、メンテナの1人が、将来的にgoogle-mockフレームワークはこれをサポートするように変更されず、ポリシーが使用法を強く推奨しないと主張している_std::auto_ptr_パラメータ。言及したように、これは私見の哲学的観点であり、モックフレームワークの機能は、どのような種類のインターフェイスを設計するか、またはサードパーティのAPIから使用できるかを操作するべきではありません。

述べたように、答えは実現可能の回避策について説明しています。

97

この投稿はかなり前の投稿だったと思いますので、おそらく今までにその答えを発見したことでしょう。

gmockは、以前は、スマートポインターを含む移動可能な型を返すモック関数をサポートしていませんでした。ただし、2017年4月、gmockは新しいアクション修飾子ByMoveを導入しました。

EXPECT_CALL(*foo_, Bar(_, )).WillOnce(Return(ByMove(some_move_only_object)));

ここで、some_move_only_objectは、たとえばstd::unique_ptr.

したがって、はい、gmockはスマートポインターを受け取る関数をモックできます。

9
jeff

モッククラスにあなたが好きなように入れてください

MOCK_METHOD0(作成、std :: unique_ptr());


以下のようにテストで

EXPECT_CALL(<mock-obj>, Create())
.WillOnce([]()->std::unique_ptr<IMyObjectThing>{
    return std::make_unique<IMyObjectThing>();
});

vs 2010がラムダをサポートしていない場合、ファンクタを使用できます

0
dstm