チートシート

Google C++ Mocking Framework チートシート

モッククラスを定義する

通常のクラスをモック化する

以下のようなクラスが与えられた場合を考えます.

class Foo {
  ...
  virtual ~Foo();
  virtual int GetSize() const = 0;
  virtual string Describe(const char* name) = 0;
  virtual string Describe(int type) = 0;
  virtual bool Process(Bar elem, int count) = 0;
};

(~Foo() は必ず virtual であることに注意してください)これのモックは,次のように定義できます.

#include "gmock/gmock.h"

class MockFoo : public Foo {
  MOCK_CONST_METHOD0(GetSize, int());
  MOCK_METHOD1(Describe, string(const char* name));
  MOCK_METHOD1(Describe, string(int type));
  MOCK_METHOD2(Process, bool(Bar elem, int count));
};

不要な呼び出しを無視する「nice」モックオブジェクト,または,それらを失敗として扱う「strict」モックオブジェクト,を作るには次のようにします:

NiceMock<MockFoo> nice_foo;     // MockFoo の派生クラス型
StrictMock<MockFoo> strict_foo;  // MockFoo の派生クラス型

クラステンプレートをモック化する

次のクラステンプレートをモック化するには

template <typename Elem>
class StackInterface {
 public:
  ...
  virtual ~StackInterface();
  virtual int GetSize() const = 0;
  virtual void Push(const Elem& x) = 0;
};

(~StackInterface() は必ず virtual であることに注意してください)MOCK_* マクロに _T を追加するだけです:

template <typename Elem>
class MockStack : public StackInterface<Elem> {
 public:
  ...
  MOCK_CONST_METHOD0_T(GetSize, int());
  MOCK_METHOD1_T(Push, void(const Elem& x));
};

モック関数の呼び出し規約を指定する

あなたのモック関数がデフォルトの呼び出し規約を利用しない場合,それを指定することができます.それには,前述の2つのセクションで説明したマクロすべてに _WITH_CALLTYPE を追加して,マクロの1番目の引数として呼び出し規約を与えます.次に例を示します.

MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n));
MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y));

ここで STDMETHODCALLTYPE は,Windows の <objbase.h> で定義されています.

モックをテストで利用する

典型的な利用の流れは次のようになります:

  1. 利用する Google Mock の名前をインポートします.Google Mock 全ての名前は,マクロなどの例外を除いて testing 名前空間に存在します.
  2. モックオブジェクトを作成します.
  3. モックオブジェクトのデフォルト Action を設定します.これはオプションです.
  4. モックオブジェクトに Expectation を設定します(どのように呼び出されるか?何をするのか?)
  5. モックオブジェクトを利用するコードを実行します.必要ならば,Google Test アサーションを用いて結果をチェックしてください.
  6. モックオブジェクトがデストラクトされると,その全ての Expectation が満足されたかどうかを Google Mock が自動的に検証します.

以下に例を示します:

using ::testing::Return;                           // #1

TEST(BarTest, DoesThis) {
  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3
      .WillByDefault(Return(1));
  // ... その他のデフォルト Action ...

  EXPECT_CALL(foo, Describe(5))                   // #4
      .Times(3)
      .WillRepeatedly(Return("Category 5"));
  // ... その他の Expectation ...

  EXPECT_EQ("good", MyProductionFunction(&foo));  // #5
}                                                 // #6

デフォルトの Action を定義する

void,bool,数値,ポインタを返す関数に対しては,Google Mock 組み込みのデフォルト Action があります.

戻り値型 T の関数のデフォルト Action を全体的にカスタマイズするには,次のようにします:

using ::testing::DefaultValue;

DefaultValue<T>::Set(value);  // 返されるデフォルト値を設定します.
// ... モックを利用します ...
DefaultValue<T>::Clear();     // デフォルト値をリセットします.

特定のメソッドのデフォルト Action をカスタマイズするには,ON_CALL() を利用します:

ON_CALL(mock_object, method(matchers))
    .With(multi_argument_matcher)  ?
    .WillByDefault(action);

Expectation を設定する

EXPECT_CALL() は,モックメソッドに Expectation を設定します(どのように呼び出されるか?何をするのか?)

EXPECT_CALL(mock_object, method(matchers))
    .With(multi_argument_matcher)  ?
    .Times(cardinality)            ?
    .InSequence(sequences)         *
    .After(expectations)           *
    .WillOnce(action)              *
    .WillRepeatedly(action)        ?
    .RetiresOnSaturation();        ?

Times() が省略された場合,cardinality は次のように仮定されます:

  • WillOnce() も WillRepeatedly() もない場合,Times(1).
  • WillOnce() が n 個あり,WillRepeatedly() がない場合,Times(n).ただし, n >= 1.
  • WillOnce() が n 個あり,WillRepeatedly() が 1 個ある場合,Times(AtLeast(n)).ただし, n >= 0.

EXPECT_CALL() がないメソッドは,何度でも自由に呼び出され,そのたびにデフォルトアクションが実行されます.

Matchers

matcher は,単一の引数にマッチします.これは,ON_CALL() または EXPECT_CALL() 内で利用したり,また値を直接検証するために利用することができます..

   
EXPECT_THAT(value, matcher) value が matcher にマッチすることをアサートします.
ASSERT_THAT(value, matcher) 致命的な失敗を生成することを除いて,EXPECT_THAT(value, matcher) と同じです.

組み込みの matcher (argument は関数の引数)は,いくつかのカテゴリに分類されます.

ワイルドカード

   
_ argument は,正しい型の任意の値をとれます.
A<type>() or An<type>() argument は,type 型の任意の値をとれます.

一般的な比較

   
Eq(value) または value argument == value
Ge(value) argument >= value
Gt(value) argument > value
Le(value) argument <= value
Lt(value) argument < value
Ne(value) argument != value
IsNull() argument は NULL ポインタ(生ポインタ,またはスマートポインタ).
NotNull() argument は NULL ポインタではない(生ポインタ,またはスマートポインタ).
Ref(variable) argument は variable の参照.
TypedEq<type>(value) argument の type 型で,value に等しい.モック関数がオーバーロードされた場合,Eq(value) の代わりにこれを使う必要があるかもしれません.

Ref() を除いて,これらの matcher は,後から変更したり破棄したりするのに備えて value のコピーを作ります.コンパイラが value が public なコピーコンストラクタを持っていないというエラーを出した場合,例えば,Eq(ByRef(non_copyable_value)) というように ByRef() でラップしてみてくださいこれを使う場合,non_copyable_value を後から変更したり,あなたの定義した matcher の意味を変更したり,決してしないようにしてください.

浮動小数点 Matcher

   
DoubleEq(a_double) argument は,a_double とおよそ等しい double 型の値.2つの NaN は等しくないとされます.
FloatEq(a_float) argument は,a_float とおよそ等しい float 型の値.2つの NaN は等しくないとされます.
NanSensitiveDoubleEq(a_double) argument は,a_double とおよそ等しい double 型の値.2つの NaN は等しいとされます.
NanSensitiveFloatEq(a_float) argument は,a_float とおよそ等しい float 型の値.2つの NaN は等しいとされます.

これらの matcher は,(Google Test で利用されているものと同様に)ULP に基づいた比較を行います.ここでは,期待する値の絶対値に基づいた適切な誤差範囲が自動的に利用されます.DoubleEq() と FloatEq() は IEEE 標準に従い,NaN 同士の等価性を評価した場合に false を返します.NanSensitive* バージョンは,2つの NaN を等しい値として扱います.この動作を望むユーザも多いでしょう.

文字列 Matcher

argument は C 文字列,または C++ string オブジェクトのどちらでも利用できます.

   
ContainsRegex(string) argument は,与えられた正規表現にマッチします.
EndsWith(suffix) argument の末尾が,文字列 suffix です.
HasSubstr(string) argument が,その部分文字列として string を含みます.
MatchesRegex(string) argument の先頭から末尾までが,与えられた正規表現にマッチします.
StartsWith(prefix) argument の先頭が,文字列 prefix です.
StrCaseEq(string) argument は,string に等しい.大文字小文字は無視されます.
StrCaseNe(string) argument は,string に等しくない.大文字小文字は無視されます.
StrEq(string) argument は,string と等しい.
StrNe(string) argument は,string と等しくない.

StrCaseEq() ,StrCaseNe() ,StrEq() ,StrNe() は,ワイド文字列に対しても動作します.

コンテナ Matcher

STL スタイルのコンテナの多くは == をサポートしています.よって,Eq(expected_container) または単に expected_container を使えば,正確にコンテナにマッチすることができます.しかし,要素をインラインで書きたい,より柔軟にマッチさせたい,メッセージを充実させたい,など場合は,以下を利用できます:

   
Contains(e) argument は,e (値または matcher)にマッチする要素を含みます.
Each(e) argument は,すべての要素が e (値または matcher)にマッチするコンテナです.
ElementsAre(e0, e1, ..., en) argument は,n + 1 個の要素を持ち,i-番目の要素は ei (値または matcher)にマッチします.0 から 10 までの引数をとれます.
ElementsAreArray(array) または ElementsAreArray(array, count) 期待する要素の値/matcher がC形式の配列で表現されることを除いて,ElementsAre() と同じです.
ContainerEq(container) 失敗メッセージにも片方のコンテナだけに存在する要素が表示される点を除いて,Eq(container) と同じです.
Pointwise(m, container) argument は,container と同数の要素を持ち,全ての i に対して(argument の i-番目の要素,container の i-番目の要素が)m にマッチします.ここで m は,2要素タプル形式の matcher です.例えば Pointwise(Le(), upper_bounds) は,argument の各要素が,対応する upper_bounds の要素を超えないかどうかを検証します.

これらの matcher は,次のようなものにもマッチします:

  1. 参照渡しされたネイティブな配列(例えば, Foo(const int (&a)[5]) )
  2. ポインタと長さで渡された配列(例えば, Bar(const T* buffer, int len) – 複数の引数をとる Matcher を参照してください.

ここで,配列は多次元配列(例えば,要素が配列)でも構いません.

メンバ Matcher

   
Field(&class::field, m) argument.field(argument がただのポインタの場合は argument->field )は,matcher m にマッチします.ここで,argument は class 型のオブジェクトです.
Key(e) argument.first は,e (値または matcher)にマッチします.例えば,Contains(Key(Le(5))) は,マップに key <=5 が含まれていることを検証します.
Pair(m1, m2) argument は,1番目のフィールドが m1 に, 2番目のフィールドが m2 にマッチする std::pair です.
Property(&class::property, m) argument.property() (argument がただのポインタの場合は argument->property() )は,matcer m にマッチします.ここで,argument は class 型のオブジェクトです.

関数またはファンクタの結果のマッチング

   
ResultOf(f, m) f(argument) は,matcher にマッチします.ここで f は関数またはファンクタです.

ポインタ Matcher

   
Pointee(m) argument (スマートポンタ,または生ポインタ)が指し示す値は,matcher m にマッチします.

複数の引数をとる Matcher

理論的には,すべての matcher は単一の値にマッチします.「複数の引数をとる」 matcher は,単にタプルにマッチする matcher です.以下の matcher は,タプル (x, y) にマッチさせるために利用できます:

   
Eq() x == y
Ge() x >= y
Gt() x > y
Le() x <= y
Lt() x < y
Ne() x != y

以下のセレクタを利用すると,引数の一部を抜き出し(または,順番を入れ替え)て,マッチングさせることができます

   
AllArgs(m) m と等価です..With(AllArgs(m)) のシンタックスシュガーとして役立ちます.
Args<N1, N2, ..., Nk>(m) (0基準のインデックスによって) k 要素のタプルが引数から選択され,それが m にマッチします.例えば, Args<1, 2>(Eq()).

複合 Matcher

1つまたは複数の matcher から, 新たに別の matcher を作ることができます.

   
AllOf(m1, m2, ..., mn) argument は,m1 から mn までの全ての matcher にマッチします.
AnyOf(m1, m2, ..., mn) argument は,m1 から mn までの matcher のうち,少なくとも1つにマッチします.
Not(m) argument は,matcher m にマッチしません.

Matcher のアダプタ

   
MatcherCast<T>(m) matcher m を,型 Matcher<T> にキャストします.
SafeMatcherCast<T>(m) matcher m を,型 Matcher<T> に安全にキャストします.
Truly(predicate) predicate(argument) は,C++ で true と判断されるなにかを返します.predicate は,関数またはファンクタです.

述語関数としての Matcher

   
Matches(m) argument が m にマッチする場合に true を返す,1変数関数です.
ExplainMatchResult(m, value, result_listener) value が m にマッチする場合に true を返し,その結果を result_listener に説明します.
Value(x, m) x の値が m にマッチする場合に true を返します.

Matcher を定義する

   
MATCHER(IsEven, “”) { return (arg % 2) == 0; } 偶数にマッチする matcher IsEven() を定義します.
MATCHER_P(IsDivisibleBy, n, “”) { *result_listener << “where the remainder is ” << (arg % n); return (arg % n) == 0; } n の倍数にマッチする matcher IsDivisibleBy(n) を定義します.
MATCHER_P2(IsBetween, a, b, std::string(negation ? “isn’t” : “is”) + ” between ” + PrintToString(a) + ” and ” + PrintToString(b)) { return a <= arg && arg <= b; } [a, b] の範囲内の値にマッチする matcher IsBetween(a, b) を定義します.

注意:

  1. MATCHER* マクロは,関数やクラスの内部では利用できません.
  2. matcher 本体は,純関数的である必要があります(つまり,いかなる副作用もなく,マッチさせる値と matcher のパラメータだけで結果が決まります).
  3. PrintToString(x) を利用して,任意の型の値 x を文字列に変換することができます.

テストアサーションとしての Matcher

   
ASSERT_THAT(expression, m) expression の値が matcher m にマッチしなかった場合に,致命的な失敗を生成します.
EXPECT_THAT(expression, m) expression の値が matcher m にマッチしなかった場合に,致命的ではない失敗を生成します.

Actions

Action は,モック関数が呼ばれたときに何をするのかを規定します.

値を返す

   
Return() void モック関数から返ります.
Return(value) value を返します.value の型がモック関数の戻り値型と異なる場合,value の型が変換されます.これは,Action 実行時ではなく,Expectation が設定されるときに行われます.
ReturnArg<N>() N-番目(0基準)の argument を返します.
ReturnNew<T>(a1, ..., ak) new T(a1, ..., ak); を返します.毎回異なるオブジェクトが作成されます.
ReturnNull() Null ポインタを返します.
ReturnPointee(ptr) ptr で指定される値を返します.
ReturnRef(variable) variable の参照を返します.
ReturnRefOfCopy(value) value のコピーの参照を返します.このコピーは,Action 時にのみ有効です.

副作用

   
Assign(&variable, value) value を variable に代入します.
DeleteArg<N>() N-番目(0基準)の argument を削除します.これはポインタである必要があります.
SaveArg<N>(pointer) N-番目(0基準)の argument を *pointer に保存します.
SaveArgPointee<N>(pointer) N-番目(0基準)の argument によって指される値を *pointer に保存します.
SetArgReferee<N>(value) N-番目(0基準)の argument によって参照される変数に,value を代入します.
SetArgPointee<N>(value) N-番目(0基準)の argument によって指される変数に,value を代入します.
SetArgumentPointee<N>(value) SetArgPointee<N>(value) と同じです.非推奨.v1.7.0 で廃止予定です.
SetArrayArgument<N>(first, last) 入力範囲 [first, last) の要素を,N-番目(0基準)の argument (これは,ポインタまたはイテレータ)によって指される配列にコピーします.Action は,入力範囲内の要素の所有権を持ちません.
SetErrnoAndReturn(error, value) error にエラー番号を設定して,value を返します.
Throw(exception) 与えられた exception を投げます.これは任意のコピー可能な値です.v1.1.0 以降で利用できます.

関数またはファンクタを Action として利用する

   
Invoke(f) モック関数に渡された argument を与えて f を呼び出します.ここで f は,グローバルで static な関数またはファンクタです.
Invoke(object_pointer, &class::method) モック関数に渡された argument を与えてオブジェクトの method を呼び出します.
InvokeWithoutArgs(f) f を呼び出します.ここで f は,グローバルで static な関数またはファンクタです.また,f は引数をとってはいけません.
InvokeWithoutArgs(object_pointer, &class::method) オブジェクトの,引数を取らない method を呼び出します
InvokeArgument<N>(arg1, arg2, ..., argk) モック関数のN-番目(0基準)の argument を呼び出します.これは k この引数をとる,関数またはファンクタである必要があります.

呼び出された関数の戻り値は,Action の戻り値として利用されます.

Invoke*() で利用される関数またはファンクタを定義する際,利用しない任意のパラメータを Unused として宣言することができます:

double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); }
...
EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));

InvokeArgument<N>(...) で,引数を参照渡しする必要があるならば,ByRef() でラップしてください.例えば:

InvokeArgument<2>(5, string("Hi"), ByRef(foo))

モック関数の2番目の argument に,5 と string(“Hi”) が値渡しされ,foo が参照渡しされます.

デフォルト Action

   
DoDefault() (ON_CALL() によって指定される,または組み込みの)デフォルト Action を実行します.

注意: 技術的な理由により,DoDefault() は複合 Action 内部では利用できません.利用しようとすると,ランタイムエラーが発生します.

複合 Action

   
DoAll(a1, a2, ..., an) a1 から an までの Action が全て実行され,an の結果が毎回返されます.最初の n-1 個の Sub-Action は void を返すものでなければいけません.
IgnoreResult(a) Action a を実行し,その結果を無視します.a は,void を返してはいけません.
WithArg<N>(a) モック関数の N-番目(0基準)の argument を Action に渡し,それを実行します.
WithArgs<N1, N2, ..., Nk>(a) モック関数の引数を(0基準のインデックスで)選択し,Action a に渡して実行します.
WithoutArgs(a) 引数なしで Action a を実行します

Action を定義する

   
ACTION(Sum) { return arg0 + arg1; } モック関数の 0番目と 1番目の argument の合計を返す Action Sum() を定義します.
ACTION_P(Plus, n) { return arg0 + n; } モック関数の 0番目の argument と n との和を返す Action Plus(n) を定義します.
ACTION_Pk(Foo, p1, ..., pk) { statements; } 与えられた statements を実行する,パラメータ化された Action Foo(p1, ..., pk) を定義します.

ACTION* マクロは,関数またはマクロの中では利用できません.

Cardinalities

これらは, Times() 内で,モック関数が呼び出される回数を指定するために利用されます:

   
AnyNumber() 関数は何度でも呼び出すことができます.
AtLeast(n) 呼び出し回数は,最低でも n 回であることが期待されます.
AtMost(n) 呼び出し回数は,最高でも n 回であることが期待されます.
Between(m, n) 呼びだし回数は,m 回から n 回(これを含む)であることが期待されます.
Exactly(n) or n 呼び出しは,正確に n 回であることが期待されます.特に,n が 0 の場合は,呼び出しは起こりません.

Expectation の順序

デフォルトでは,Expectation は任意の順序でマッチすることができます.いくつかの,またはすべての Expectaion を指定した順序通りにマッチする必要がある場合,それを行う方法は2つあります.これらの方法は,独立にも一緒にも利用できます.

After 節

using ::testing::Expectation;
...
Expectation init_x = EXPECT_CALL(foo, InitX());
Expectation init_y = EXPECT_CALL(foo, InitY());
EXPECT_CALL(foo, Bar())
    .After(init_x, init_y);

これは,InitX() および InitY() が呼び出された後でのみ,Bar() を呼び出すことができる,ということを意味します.

Expectation を書くときにはまだ,事前に必要な処理の回数が不明な場合, ExpectationSet を利用して,それを数えることができます:

using ::testing::ExpectationSet;
...
ExpectationSet all_inits;
for (int i = 0; i < element_count; i++) {
  all_inits += EXPECT_CALL(foo, InitElement(i));
}
EXPECT_CALL(foo, Bar())
    .After(all_inits);

これは,全ての要素が初期化された後でのみ(ただし,要素の初期化される順番には関心がありません),Bar() を呼び出すことができる,ということを意味します.

.After() で利用した後に ExpectationSet を変更しても,.After() の意味は変わりません.

シーケンス

シーケンシャルな Expectation の長い連鎖がある場合は,シーケンスを利用して順序を指定するのが簡単です.この場合,連鎖 の中の各 Expectation に別々の名前を与える必要がありません.同じシーケンスに属する呼び出しは全て,指定された順番で呼び出される必要があります.

using ::testing::Sequence;
Sequence s1, s2;
...
EXPECT_CALL(foo, Reset())
    .InSequence(s1, s2)
    .WillOnce(Return(true));
EXPECT_CALL(foo, GetSize())
    .InSequence(s1)
    .WillOnce(Return(1));
EXPECT_CALL(foo, Describe(A<const char*>()))
    .InSequence(s2)
    .WillOnce(Return("dummy"));

これは,GetSize() および Describe() の後でのみ(これらの順序は任意です), Reset() が呼び出されることを意味します.

シーケンスに含まれる Expectation の数が多い場合には,便利な方法があります:

using ::testing::InSequence;
{
  InSequence dummy;

  EXPECT_CALL(...)...;
  EXPECT_CALL(...)...;
  ...
  EXPECT_CALL(...)...;
}

これは,dummy と同じスコープ内にあるすべての呼び出しが,その順序で発生する必要があることを意味します.dummy という名前には,特に意味はありません.

モックを検証・リセットする

Google Mock は,モックオブジェクトがデストラクトされた際に,その Expectation を検証します.また,デストラクトよりも前のタイミングでそれを行うこともできます.

using ::testing::Mock;
...
// mock_obj の Expectation を検証して削除します.
// 成功した場合のみ true を返します.
Mock::VerifyAndClearExpectations(&mock_obj);
...
// mock_obj の Expectation を検証して削除します.
// ON_CALL() で設定されたデフォルト Action も削除されます.
// 成功した場合のみ true を返します.
Mock::VerifyAndClear(&mock_obj);

Google Mock が,特定のモックオブジェクトを検証しないようにすることもできます:

Mock::AllowLeak(&mock_obj);

モッククラス

Google Mock には,便利なモッククラステンプレートが定義されています.

class MockFunction<R(A1, ..., An)> {
 public:
  MOCK_METHODn(Call, R(A1, ..., An));
};

応用は, このレシピ を参照してください.

フラグ

   
—gmock_catch_leaked_mocks=0 検証しないモックオブジェクトを失敗として報告しないようにします.
—gmock_verbose=LEVEL Google Mock メッセージの出力レベル(情報,警告,エラー)を設定します.