// これはコンパイルできます.
MOCK_METHOD1(GetSize, int(const map<int, std::string>& m));
もし戻り値の型にカンマがあれば,typedef が必要になりますが,そのようなケースは非常にまれです.
他にも,次のような利点があります:
MOCK_METHOD1(Foo, int, bool) という書き方では,そのメソッドが int を返すのか bool を返すのか,読み手が悩む可能性があります.しかし,Google Mock の構文では,そのような混乱は起こりません.
Google Mock の関数の型を書く方法は,何も新しいものではありませんが,多くの人がこれには慣れていないでしょう.同様の構文が C 言語でも利用され,tr1 の関数ライブラリでも広範囲で使われています.また,tr1 は新バージョンの STL に取り込まれるので,これと一貫性があるのはとても快適なことです.
この関数の型の構文は,実装を扱いやすいものにするために,Google Mock の API の別の部分(例えば,Action インタフェース)でも利用されています.Google Mock をより便利に使うためには,ともかくこれを学ぶ必要があります.また,MOCK_METHOD* でも同様の構文を利用しています!
コードで static/global な関数を使っています.これをモック化できますか?
できますが,いくつかの変更が必要です.
一般的にいって,static 関数をモック化したくなったとすると,それはモジュール同士がが強く結びつきすぎている(そして,柔軟性や再利用性,テスト可能性などが低下している)ことを示すサインです.おそらく,より小さなインタフェースを定義し,そのインタフェースを介してメソッドを呼び出すほうが良いでしょう.そのようなメソッドは,簡単にモック化できます.それは,ちょっとした仕事になりますが,すぐに元が取れます.
Google Testing Blog のこの ポスト が,それを見事に述べています.ぜひ見てください.
モックオブジェクトが複雑なことをする必要があり,その Action を指定するのがとても大変です.Google Mock にはがっかりです!
これが質問ではないことは分かっていますが,ともかく回答を書きます.:-)
Google Mock を使うと,C++ で簡単にモックを作ることができます.そして,あらゆる場所でそれを使おうとするかもしれません.非常に上手く使えることもあれば,えー,まったく苦痛でしかないこともあります.後者の場合では,何が問題なのでしょうか?
モックを利用せずにテストを書く場合,コードを実行して,それが正しい値を返すことや,システムが期待した状態にあることをアサートします.これは,「状態に基づくテスト(state-based testing)」と呼ばれることがあります.
モックが役立つのは,「インタラクションに基づく(interaction-based)」テストと呼ばれるものに対してです.このテストでは,すべて終わった後にシステムの状態をチェックする代わりに,モックオブジェクトが,自分自身が正しく実行されたかを検証し,エラーが起これば即座にレポートします.これにより,ユーザはエラーが発生したときの正確なコンテキストを把握することができます.これは,状態に基づくテストに比べて,より便利で経済的な場合が多いです.
もし,あなたが状態に基づくテストを行っており,実際のオブジェクトをシミュレートするためだけにテストダブルを使っているならば,フェイクを使ったほうが良いでしょう.モックは,複雑な動作を行うことを重視していないので,このような場合にモックを利用しても苦痛なだけです.もし,このようなことで悩み,モックは駄目だと思ったなら,それは単に問題に合った正しい道具を使っていないだけです.あるいは,間違った問題を解こうとしているのかもしれません.:-)
“Uninteresting function call encountered - default action taken..” という警告がでました.パニックになるべき?
いいえ,そんな必要はまったくありません.これは,単に参考のための情報です.
これは,Expectation を設定していないモック関数があり(Google Mock のルールでは,この関数呼び出しに関心が無いので,任意の回数呼び出すことができます),それが呼び出された,ということを意味しています.大丈夫,問題ありません.この関数を呼び出してはいけない,とは決めませんでしたから.
実際にはこの関数の呼び出しを許可していないつもりで,EXPECT_CALL(foo, Bar()).Times(0) を書き忘れていたのなら,どうでしょうか?それがユーザの誤りだと言える場合でも,Google Mock は,気を使って,注意表示を行います.
不要な呼び出しは1つも無いはずだと信じている場合でも,このメッセージを目にしたら,何が起こっているのかを調べてみるべきです.不要な呼び出しが起こった場合に悩まなくてもすむように,Google Mock はその関数名と引数を出力します.
カスタム Action を定義したいです.Invoke() を使うのと Action インタフェースを実装するのは,どちらが適切でしょうか?
どちらでも構いません.が,状況に応じて便利な方を選択したい,というわけですね.
あなたの Action が特定の関数型に対するものならば,通常は Invoke() を用いて定義するのが簡単でしょう.その Action が異なる型の関数内で利用される可能性がある場合(例えば,Return(value) を定義している場合)は,MakePolymorphicAction() が最も簡単です.また,関数(この内部で Action が利用されます)の型を正確に制御したい場合もありますが,その場合は,ActionInterface を実装する方法を採ります.例として,include/gmock/gmock-actions.h における Return() の実装を参照してください.
set-argument-pointee Action を使っているのですが,コンパイラが “conflicting return type specified” というエラーを出します.どういう意味でしょうか?
モックメソッドが呼ばれたときに,Google Mock がどの値を返すべきか分からないと,このエラーが起こります.SetArgPointee() を使うことで,副作用が何なのかは分かりますが,何の値を返すべきかは分かりません.DoAll() を利用して,SetArgPointee() に続けて Return() を呼ぶ必要があります.
詳細は,この レシピ を参照してください.
知りたいことが,この FAQ に載ってないのですが.
もし,疑問の答えがこの FAQ に載っていない場合でも,他にも利用できるリソースがあります:
他の ページ を読んでください.
メーリングリストの アーカイブ を検索してみてください.
googlemock@googlegroups.com で質問すると,誰かが答えてくれるかもしれません(スパム防止のため,投稿前に ディスカッショングループ に参加する必要があります).
issue tracker は,ごく少数の人間がたまに見ているだけなので,質問に答えてもらうために,ここに issue を作成するのは良い方法ではありません.
質問するときは,以下の情報をできるだけ多く提示することが役に立ちます(質問に関する情報が十分でなければ,手助けできません):
利用している Google Mock のバージョン(SVN から直接チェックアウトしているならば,リビジョン番号.Google Mock は開発中なので,最新バージョンで問題が解決されている可能性もあります)
使っている OS
コンパイラの名前とバージョン
コンパイル時のコマンドラインフラグすべて
(質問がコンパイルに関することならば,)コンパイルエラーメッセージすべて
問題を起こす実際のコード(理想的には,最小限かつ動作可能なプログラム)
よくある質問