.. _cookbook: ============ クックブック ============ .. Google C++ Mocking Framework Cookbook *Google C++ Mocking Framework クックブック* * :ref:`cookbook_creating_mock_classes` * :ref:`cookbook_mocking_private_or_protected_meethods` * :ref:`cookbook_mocking_overloaded_methods` * :ref:`cookbook_mocking_class_templates` * :ref:`cookbook_mocking_nonvirtual_methods` * :ref:`cookbook_mocking_free_functions` * :ref:`cookbook_nice_or_strict` * :ref:`cookbook_simplifying_the_interface` * :ref:`cookbook_alternative_to_mocking_concrete_classes` * :ref:`cookbook_delegating_calls_to_a_fake` * :ref:`cookbook_delegating_calls_to_a_real_object` * :ref:`cookbook_delegating_calls_to_a_parent_class` * :ref:`cookbook_using_matchers` * :ref:`cookbook_matching_argument_values_exactly` * :ref:`cookbook_using_simple_matchers` * :ref:`cookbook_combining_matchers` * :ref:`cookbook_casting_matchers` * :ref:`cookbook_selecting_overloaded_functions` * :ref:`cookbook_performing_different_actions_based_on_the_arguments` * :ref:`cookbook_matching_multiple_arguments_as_a_whole` * :ref:`cookbook_using_matchers_as_predicates` * :ref:`cookbook_using_matchers_in_gtest_assertions` * :ref:`cookbook_using_predicates_as_matchers` * :ref:`cookbook_matching_arguments_that_are_not_copyable` * :ref:`cookbook_validating_a_member_of_an_object` * :ref:`cookbook_validating_the_value_pointed_to_by_a_pointer_argument` * :ref:`cookbook_testing_a_certain_property_of_an_object` * :ref:`cookbook_matching_containers` * :ref:`cookbook_sharing_matchers` * :ref:`cookbook_setting_expectations` * :ref:`cookbook_ignoring_uninteresting_calls` * :ref:`cookbook_disallowing_unexpected_calls` * :ref:`cookbook_expecting_ordered_calls` * :ref:`cookbook_expecting_partially_ordered_calls` * :ref:`cookbook_controlling_when_an_expectation_retires` * :ref:`cookbook_using_actions` * :ref:`cookbook_returning_reference_from_mock_methods` * :ref:`cookbook_returnig_live_values_from_mock_methods` * :ref:`cookbook_combining_actions` * :ref:`cookbook_mocking_side_effects` * :ref:`cookbook_changing_a_mock_objects_behavior_based_on_the_state` * :ref:`cookbook_setting_the_default_value_for_a_return_type` * :ref:`cookbook_setting_the_default_actions_for_a_mock_method` * :ref:`cookbook_using_functions_methods_functors_as_actions` * :ref:`cookbook_invoking_a_function_method_functor_without_arguments` * :ref:`cookbook_invoking_an_argument_of_the_mock_function` * :ref:`cookbook_ignoring_an_actions_result` * :ref:`cookbook_selecting_an_actions_arguments` * :ref:`cookbook_ignoring_arguments_in_action_functions` * :ref:`cookbook_sharing_actions` * :ref:`cookbook_misc_recipes_on_using_gmook` * :ref:`cookbook_forcing_a_varification` * :ref:`cookbook_using_check_points` * :ref:`cookbook_mocking_destructors` * :ref:`cookbook_using_gmock_and_threads` * :ref:`cookbook_controlling_how_much_information_gmock_prints` * :ref:`cookbook_running_tests_in_emacs` * :ref:`cookbook_fusing_gmock_source_files` * :ref:`cookbook_extending_gmock` * :ref:`cookbook_writing_new_matchers_quickly` * :ref:`cookbook_writing_new_parameterized_matchers_quickly` * :ref:`cookbook_writing_new_monomorphic_matchers` * :ref:`cookbook_writing_new_polymorphic_matchers` * :ref:`cookbook_writing_new_cardinalities` * :ref:`cookbook_writing_new_actions_quickly` * :ref:`cookbook_writing_new_parameterized_actions_quickly` * :ref:`cookbook_restricting_the_type_of_an_argument_or_parameter_in_an_ACTION` * :ref:`cookbook_writing_new_action_templates_quickly` * :ref:`cookbook_using_the_ACTION_objects_type` * :ref:`cookbook_writing_new_monomorphic_actions` * :ref:`cookbook_writing_new_polymorphic_actions` * :ref:`cookbook_teaching_gmock_how_to_print_your_values` .. You can find recipes for using Google Mock here. If you haven't yet, please read the ForDummies document first to make sure you understand the basics. ここでは,Google Mock を利用したレシピを紹介します.もし未読ならば,基礎を確実に理解するために,ドキュメント :ref:`for_dummies` を読んでください. .. Note: Google Mock lives in the testing name space. For readability, it is recommended to write using ::testing::Foo; once in your file before using the name Foo defined by Google Mock. We omit such using statements in this page for brevity, but you should do it in your own code. **注意:** Google Mock は testing 名前空間に属しています.読みやすいように,Google Mock で定義された Foo を利用する各ファイルで,それより前に using ::testing::Foo; を書くことをお勧めします.このページでは,簡潔さのためにそのような文を省略していますが,自分のコードではちゃんと書いてください. .. Creating Mock Classes .. _cookbook_creating_mock_classes: モッククラスを作る =================== .. Mocking Private or Protected Methods .. _cookbook_mocking_private_or_protected_meethods: Private または Protected なメソッドをモック化する --------------------------------------------------------------- .. You must always put a mock method definition (MOCK_METHOD*) in a public: section of the mock class, regardless of the method being mocked being public, protected, or private in the base class. This allows ON_CALL and EXPECT_CALL to reference the mock function from outside of the mock class. (Yes, C++ allows a subclass to change the access level of a virtual function in the base class.) Example: モック化されるメソッドが基底クラスにおいて public か protected か private か,に関わらず,モックメソッドの定義(MOCK_METHOD*)は,必ずモッククラスの public: セクションに書く必要があります.これによって,モッククラス外部の ON_CALL および EXPECT_CALL が,モック関数を参照できます.(そう,C++ では,基底クラスの仮想関数のアクセスレベルを派生クラスで変更することができます.)以下に例を示します: .. code-block:: c class Foo { public: ... virtual bool Transform(Gadget* g) = 0; protected: virtual void Resume(); private: virtual int GetTimeOut(); }; class MockFoo : public Foo { public: ... MOCK_METHOD1(Transform, bool(Gadget* g)); // 基底クラスのメソッドが protected や private でも // 以下は必ず public にしてください. MOCK_METHOD0(Resume, void()); MOCK_METHOD0(GetTimeOut, int()); }; .. Mocking Overloaded Methods .. _cookbook_mocking_overloaded_methods: オーバーロードされたメソッドをモック化する ----------------------------------------------------------------- .. You can mock overloaded functions as usual. No special attention is required: オーバーロードされた関数も同じようにモック化することができます.特に気を付けることはありません. .. code-block:: c class Foo { ... // Foo を継承するので,これは必ず virtual. virtual ~Foo(); // 引数の型や数を変えてオーバーロードされます. virtual int Add(Element x); virtual int Add(int times, Element x); // オブジェクトの const のありなしでオーバーロードされます. virtual Bar& GetBar(); virtual const Bar& GetBar() const; }; class MockFoo : public Foo { ... MOCK_METHOD1(Add, int(Element x)); MOCK_METHOD2(Add, int(int times, Element x); MOCK_METHOD0(GetBar, Bar&()); MOCK_CONST_METHOD0(GetBar, const Bar&()); }; .. test: if you don't mock all versions of the overloaded method, the compiler will give you a warning about some methods in the base class being hidden. To fix that, use using to bring them in scope: **注意:** オーバーロードされたメソッドの全バージョンをモック化するわけではない場合,基底クラスのメソッドが見えない状態になっている,という警告をコンパイラが出します.これを修正するには,スコープ内にインポートするために using を使ってください: .. code-block:: c class MockFoo : public Foo { ... using Foo::Add; MOCK_METHOD1(Add, int(Element x)); // int Add(int times, Element x); の方はモック化したくありません. ... }; .. Mocking Class Templates .. _cookbook_mocking_class_templates: クラステンプレートをモック化する ------------------------------------------- .. To mock a class template, append _T to the MOCK_* macros: クラステンプレートをモック化するには,MOCK_* マクロに _T を追加します: .. code-block:: c template class StackInterface { ... // StackInterface を継承するので,これは必ず virtual. virtual ~StackInterface(); virtual int GetSize() const = 0; virtual void Push(const Elem& x) = 0; }; template class MockStack : public StackInterface { ... MOCK_CONST_METHOD0_T(GetSize, int()); MOCK_METHOD1_T(Push, void(const Elem& x)); }; .. Mocking Nonvirtual Methods .. _cookbook_mocking_nonvirtual_methods: 非仮想メソッドをモック化する ------------------------------------- .. Google Mock can mock non-virtual functions to be used in what we call hi-perf dependency injection. Google Mock は, *高効率な依存性の注入* 時に利用するために,非仮想関数をモック化することができます. .. In this case, instead of sharing a common base class with the real class, your mock class will be unrelated to the real class, but contain methods with the same signatures. The syntax for mocking non-virtual methods is the same as mocking virtual methods: この場合,実際のクラスとモッククラスで基底クラスを共有するのではなく,モッククラスと実際のクラスは無関係になりますが,これらは同じシグネチャのメソッドを持ちます.非仮想メソッドをモック化するための構文は,仮想メソッドをモック化する際と同様です. .. code-block:: c // 簡単なパケットストリームクラス.virtual なメンバはありません. class ConcretePacketStream { public: void AppendPacket(Packet* new_packet); const Packet* GetPacket(size_t packet_number) const; size_t NumberOfPackets() const; ... }; // モックパケットストリームクラス.何も継承しませんが, // GetPacket() と NumberOfPackets() は定義されます. class MockPacketStream { public: MOCK_CONST_METHOD1(GetPacket, const Packet*(size_t packet_number)); MOCK_CONST_METHOD0(NumberOfPackets, size_t()); ... }; .. Note that the mock class doesn't define AppendPacket(), unlike the real class. That's fine as long as the test doesn't need to call it. モッククラスは,実際のクラスとは異なり AppendPacket() を定義していないことに注意してください.テストがこれの呼び出しを必要としない限り,問題はありません. .. Next, you need a way to say that you want to use ConcretePacketStream in production code, and use MockPacketStream in tests. Since the functions are not virtual and the two classes are unrelated, you must specify your choice at compile time (as opposed to run time). 次に,製品版コードでは ConcretePacketStream を,テストコードでは MockPacketStream を使用する,ということを明示する必要があります.この関数は仮想関数ではなく,2つのクラスは無関係なので,(実行時ではなく)コンパイル時に指定する必要があります. .. One way to do it is to templatize your code that needs to use a packet stream. More specifically, you will give your code a template type argument for the type of the packet stream. In production, you will instantiate your template with ConcretePacketStream as the type argument. In tests, you will instantiate the same template with MockPacketStream. For example, you may write: 方法の1つは,パケットストリームを利用しなければならないコードをテンプレート化することです.より具体的には,コードにテンプレート型引数を導入して,これをパケットストリームの型とします.製品では,テンプレートに型引数として ConcretePacketStream を与えてインスタンス化します.また,テストでは,同じテンプレートに MockPacketStream を与えてインスタンス化します.次に例を示します: .. code-block:: c template void CreateConnection(PacketStream* stream) { ... } template class PacketReader { public: void ReadPackets(PacketStream* stream, size_t packet_num); }; .. Then you can use CreateConnection() and PacketReader in production code, and use CreateConnection() and PacketReader in tests. そして,製品コードでは,CreateConnection() と PacketReader を,テストでは,CreateConnection() と PacketReader を利用します. .. code-block:: c MockPacketStream mock_stream; EXPECT_CALL(mock_stream, ...)...; // ... mock_stream に,いろいろな Expectation を設定します ... PacketReader reader(&mock_stream); // ... reader を実行します ... .. Mocking Free Functions .. _cookbook_mocking_free_functions: フリー関数をモック化する ----------------------------------- .. It's possible to use Google Mock to mock a free function (i.e. a C-style function or a static method). You just need to rewrite your code to use an interface (abstract class). Google Mock を使って,フリー関数(つまり,C形式の関数,または static メソッド)をモック化することもできます.必要なのは,コードをインタフェース(抽象クラス)を使うように書き直すことだけです. .. Instead of calling a free function (say, OpenFile) directly, introduce an interface for it and have a concrete subclass that calls the free function: フリー関数(例えば,OpenFile)を直接呼び出す代わりに,そのインタフェースを導入し,具象クラス派生させ,そこでフリー関数を呼び出します. .. code-block:: c class FileInterface { public: ... virtual bool Open(const char* path, const char* mode) = 0; }; class File : public FileInterface { public: ... virtual bool Open(const char* path, const char* mode) { return OpenFile(path, mode); } }; .. Your code should talk to FileInterface to open a file. Now it's easy to mock out the function. コードでは ,ファイルを開くために FileInterface を利用します.このように,フリー関数をモック化するのは簡単です. .. This may seem much hassle, but in practice you often have multiple related functions that you can put in the same interface, so the per-function syntactic overhead will be much lower. これは面倒に見えるかもしれませんが,実際には,同じインタフェースに入れられる複数の関連する関数があるので,1つの関数を書く上での労力はより小さくなります. .. If you are concerned about the performance overhead incurred by virtual functions, and profiling confirms your concern, you can combine this with the recipe for mocking non-virtual methods. 仮想関数によるパフォーマンスオーバーヘッドが心配で,実際にそれをプロファイラで確認したなら, :ref:`cookbook_mocking_nonvirtual_methods` のレシピと併用することもできます. .. Nice Mocks and Strict Mocks .. _cookbook_nice_or_strict: Nice モックと Strict モック ------------------------------------ .. If a mock method has no EXPECT_CALL spec but is called, Google Mock will print a warning about the "uninteresting call". The rationale is: EXPECT_CALL が指定されていないにもかかわらず,そのメソッドが呼び出されると,Google Mock は,"uninteresting call" の警告を出力します.その理由は次の通りです: .. New methods may be added to an interface after a test is written. We shouldn't fail a test just because a method it doesn't know about is called. .. However, this may also mean there's a bug in the test, so Google Mock shouldn't be silent either. If the user believes these calls are harmless, he can add an EXPECT_CALL() to suppress the warning. * テストを書いた後にインタフェースに新しいメソッドが追加された可能性がある.知らないメソッドが呼び出されたから,という理由のみでテストを失敗させるべできはない. * しかし,テストのバグという可能性もあるので,Google Mock は黙って見過ごすべきでもない.この呼び出しが無害だとユーザが分かっているならば,EXPECT_CALL() を追加してこの警告を消すことができる. .. However, sometimes you may want to suppress all "uninteresting call" warnings, while sometimes you may want the opposite, i.e. to treat all of them as errors. Google Mock lets you make the decision on a per-mock-object basis. しかし,全ての "uninteresting call" 警告を抑制したい場合や,その正反対の場合,例えば,全部エラーとして扱いたい,といった場合があるかもしれません. Google Mock では,モックオブジェクト毎にそれを決めることができます. .. Suppose your test uses a mock class MockFoo: テストで MockFoo というモッククラスを使う場合を考えます: .. code-block:: c TEST(...) { MockFoo mock_foo; EXPECT_CALL(mock_foo, DoThis()); // ... mock_foo を利用するコード ... } .. If a method of mock_foo other than DoThis() is called, it will be reported by Google Mock as a warning. However, if you rewrite your test to use NiceMock instead, the warning will be gone, resulting in a cleaner test output: DoThis() 以外の mock_foo メソッドが呼び出されると,Google Mock によって警告が出されます.しかし,代わりに NiceMock を使うようにテストを書き直すと,この警告は消え,綺麗な出力結果になります. .. code-block:: c using ::testing::NiceMock; TEST(...) { NiceMock mock_foo; EXPECT_CALL(mock_foo, DoThis()); // ... mock_foo を利用するコード ... } .. NiceMock is a subclass of MockFoo, so it can be used wherever MockFoo is accepted. NiceMock は,MockFoo の派生クラスなので,MockFoo が使える場所ならどこでも利用可能です. .. It also works if MockFoo's constructor takes some arguments, as NiceMock "inherits" MockFoo's constructors: NiceMock は MockFoo のコンストラクタを「継承」するので,MockFoo のコンストラクタが引数をとる場合も問題なく動作します. .. code-block:: c using ::testing::NiceMock; TEST(...) { NiceMock mock_foo(5, "hi"); // MockFoo(5, "hi") を呼び出します. EXPECT_CALL(mock_foo, DoThis()); // ... mock_foo を利用するコード ... } .. The usage of StrictMock is similar, except that it makes all uninteresting calls failures: StrictMock の使い方も同様ですが,こちらは不要な呼び出しをすべて失敗として扱います. .. code-block:: c using ::testing::StrictMock; TEST(...) { StrictMock mock_foo; EXPECT_CALL(mock_foo, DoThis()); // ... mock_foo を利用するコード ... // mock_foo の DoThis() 以外のメソッドが呼び出されると, // テストは失敗します. } .. There are some caveats though (I don't like them just as much as the next guy, but sadly they are side effects of C++'s limitations): いくつかの注意事項があります(私はこういうのが人一倍好きではないのですが,悲しいかな c++ の制限による副作用なのです): .. NiceMock and StrictMock only work for mock methods defined using the MOCK_METHOD* family of macros directly in the MockFoo class. If a mock method is defined in a base class of MockFoo, the "nice" or "strict" modifier may not affect it, depending on the compiler. In particular, nesting NiceMock and StrictMock (e.g. NiceMock >) is not supported. .. The constructors of the base mock (MockFoo) cannot have arguments passed by non-const reference, which happens to be banned by the Google C++ style guide. .. During the constructor or destructor of MockFoo, the mock object is not nice or strict. This may cause surprises if the constructor or destructor calls a mock method on this object. (This behavior, however, is consistent with C++'s general rule: if a constructor or destructor calls a virtual method of this object, that method is treated as non-virtual. In other words, to the base class's constructor or destructor, this object behaves like an instance of the base class, not the derived class. This rule is required for safety. Otherwise a base constructor may use members of a derived class before they are initialized, or a base destructor may use members of a derived class after they have been destroyed.) #. NiceMock と StrictMock は,MockFoo クラス内で **直接** MOCK_METHOD* 関連のマクロを使って定義されたモックメソッドに対してのみ有効です.MockFoo の **基底クラス** で定義されたモックメソッドに対して,"nice" や "strict" の修飾子が影響するかどうかはコンパイラ依存です.特に,NiceMock と StrictMock がネストしている場合(例えば,NiceMock >)はサポートされません. #. 基底モッククラス(MockFoo)のコンストラクタは,const ではない参照で渡された引数をとることができません.これは,図らずも `Google C++ style guide `_ で禁止されています. #. MockFoo のコンストラクタやデストラクタの実行中は,モックオブジェクトは nice や strict ではありません.なので,コンストラクタやデストラクタが,this オブジェクトのモックメソッドを呼び出した場合,予期しないことが起こる可能性があります.(しかし,この挙動は,C+++ の一般的なルールに矛盾するものではありません:コンストラクタやデストラクトが,this オブジェクトの仮想メソッドを呼び出した場合,そのメソッドは非仮想関数として扱われます.言い換えれば,基底クラスのコンストラクタやデストラクタに対して,this オブジェクトは,派生クラスではなく基底クラスのインスタンスのように振る舞う,ということです.このルールは安全性のために必要です.これがなければ,基底クラスのコンストラクタが初期化前の派生クラスのメンバを使う可能性や,基底クラスのデストラクタが破棄されてしまった派生クラスのメンバを使う可能性があります.) .. Finally, you should be very cautious when using this feature, as the decision you make applies to all future changes to the mock class. If an important change is made in the interface you are mocking (and thus in the mock class), it could break your tests (if you use StrictMock) or let bugs pass through without a warning (if you use NiceMock). Therefore, try to specify the mock's behavior using explicit EXPECT_CALL first, and only turn to NiceMock or StrictMock as the last resort. 最後に,この機能は,モッククラスの今後すべてに変更を適用するという決断なので, **非常に慎重に** 利用するべきです.モック化しているインタフェースに(そして,モックラスにも)重大な変更が起こった場合,テストが破壊される可能性(StrictMock を利用する場合)や,バグが警告されず見過ごされる可能性(NiceMock を利用する場合)があります.したがって,まずは EXPECT_CALL を明示してモックの挙動を指定しましょう.NiceMock や StrictMock は最後の手段と考えるべきです. .. Simplifying the Interface without Breaking Existing Code .. _cookbook_simplifying_the_interface: 既存のコードを壊さずにインタフェースを単純化する ------------------------------------------------------------------- .. Sometimes a method has a long list of arguments that is mostly uninteresting. For example, メソッドが多くの引数をとるものの,そのほとんどが不要,という場合があります. .. code-block:: c class LogSink { public: ... virtual void send(LogSeverity severity, const char* full_filename, const char* base_filename, int line, const struct tm* tm_time, const char* message, size_t message_len) = 0; }; .. This method's argument list is lengthy and hard to work with (let's say that the message argument is not even 0-terminated). If we mock it as is, using the mock will be awkward. If, however, we try to simplify this interface, we'll need to fix all clients depending on it, which is often infeasible. このメソッドの引数リストは長く,扱いにくいものです(引数 message が 0-終端でさえないと仮定しています).もしこれを,そのままモック化すると,モックの利用が大変になります.かといって,このインタフェースを簡単にしようとすると,これに依存するもの全てを修正しなければならなくなり,これは大抵の場合不可能です. .. The trick is to re-dispatch the method in the mock class: メソッドをモッククラスに再ディスパッチするのがミソです: .. code-block:: c class ScopedMockLog : public LogSink { public: ... virtual void send(LogSeverity severity, const char* full_filename, const char* base_filename, int line, const tm* tm_time, const char* message, size_t message_len) { // ログの重要度(severity),完全なファイル名(full_filename), // そして,メッセージ(message) のみが必要とされます. Log(severity, full_filename, std::string(message, message_len)); } // モックメソッドを実装します: // // void Log(LogSeverity severity, // const string& file_path, // const string& message); MOCK_METHOD3(Log, void(LogSeverity severity, const string& file_path, const string& message)); }; .. By defining a new mock method with a trimmed argument list, we make the mock class much more user-friendly. 限定された引数をとる新しいモックメソッドを定義することで,ユーザフレンドリーなモッククラスを作成できます. .. Alternative to Mocking Concrete Classes .. _cookbook_alternative_to_mocking_concrete_classes: 具象クラスのモック化に対する代替案 --------------------------------------------- .. Often you may find yourself using classes that don't implement interfaces. In order to test your code that uses such a class (let's call it Concrete), you may be tempted to make the methods of Concrete virtual and then mock it. インタフェースを持たないクラスを利用することも多々あるかもしれません.そして,そのようなクラス(これを,具象クラスと呼びましょう)を利用するコードをテストするために,具象クラスのメソッドを仮想メソッドにして,それをモック化するという誘惑に駆られるかもしれません. .. Try not to do that. そのようなことはしないでください. .. Making a non-virtual function virtual is a big decision. It creates an extension point where subclasses can tweak your class' behavior. This weakens your control on the class because now it's harder to maintain the class' invariants. You should make a function virtual only when there is a valid reason for a subclass to override it. 非仮想関数を仮想関数に変更するのは重大な決断です.これによって,派生クラスがあなたのクラスの挙動を変更できてしまう拡張ポイントが作成されます.クラスを不変な状態に保つのが難しくなるので,そのクラスに対するあなたの支配力が弱まります.派生クラスがそれをオーバーライドする正当な理由がある場合のみ,仮想関数に変更するべきでしょう. .. Mocking concrete classes directly is problematic as it creates a tight coupling between the class and the tests - any small change in the class may invalidate your tests and make test maintenance a pain. 具象クラスを直接モック化するのも問題です.そのクラスとテストが密接に結びついてしまうので,クラスの些細な変更によってテストが無効になり,テストのメンテナンスが大変面倒なことになるかもしれません. .. To avoid such problems, many programmers have been practicing "coding to interfaces": instead of talking to the Concrete class, your code would define an interface and talk to it. Then you implement that interface as an adaptor on top of Concrete. In tests, you can easily mock that interface to observe how your code is doing. このような問題を避けるために,多くのプログラマが「インタフェースに対するコーディング」を実践してきました:この場合,具象クラスを扱う代わりに,あなたのコードでインタフェースを定義し,それに対して処理を行うことになります.そしてインタフェースは,具象クラスにかぶせるアダプタとして実装されます.テストでは,そのインタフェースをモック化して,コードの挙動をより簡単に観測できます. .. This technique incurs some overhead: このテクニックは,多少のオーバーヘッドを引き起こします: .. You pay the cost of virtual function calls (usually not a problem). .. There is more abstraction for the programmers to learn. * 仮想関数を呼び出すコストを払うことになります(これが問題になることは,ほとんどありませんが). * プログラマは抽象化について学ぶ必要があります. .. However, it can also bring significant benefits in addition to better testability: しかし,テストしやすくなる上に,次のような十分な恩恵がもたらされます: .. Concrete's API may not fit your problem domain very well, as you may not be the only client it tries to serve. By designing your own interface, you have a chance to tailor it to your need - you may add higher-level functionalities, rename stuff, etc instead of just trimming the class. This allows you to write your code (user of the interface) in a more natural way, which means it will be more readable, more maintainable, and you'll be more productive. .. If Concrete's implementation ever has to change, you don't have to rewrite everywhere it is used. Instead, you can absorb the change in your implementation of the interface, and your other code and tests will be insulated from this change. .. Some people worry that if everyone is practicing this technique, they will end up writing lots of redundant code. This concern is totally understandable. However, there are two reasons why it may not be the case: あるサービスを利用しているのがあなた1人ではなく,その具象クラスの API が,あなたの問題に対してあまり適切ではないことがあるかもしれません.あなた自身のインタフェースを設計すれば,単にクラスを整理するだけでなく,高度な機能の追加や,名前の変更などを行って,それを自分の必要にうまく合わせることができる場合があります.これによって,(インタフェースを利用する)あなたのコードがより自然で読みやすいものになり,生産性が向上します. 具象クラスの実装の変更が必要になったとしても,それを利用している側では書き換えの必要がありません.あなたのインタフェースの実装がその変更を吸収して,そのほかのコードを変更の影響から守ることができます. このテクニックを皆が使うと冗長なコードが大量に書かれる羽目にならないか,と心配する人もいます.この心配はもっともですが,そうはならない理由が2つあります: .. Different projects may need to use Concrete in different ways, so the best interfaces for them will be different. Therefore, each of them will have its own domain-specific interface on top of Concrete, and they will not be the same code. .. If enough projects want to use the same interface, they can always share it, just like they have been sharing Concrete. You can check in the interface and the adaptor somewhere near Concrete (perhaps in a contrib sub-directory) and let many projects use it. * 異なるプロジェクトでは,異なる方法で具象クラスを使う必要がありますので,最適なインタフェースはそれぞれ違ったものになります.したがって,具象クラスに各自が特有のインタフェースをかぶせることになり,それらは同じコードにはなりません. * 同じインタフェースを使いたいプロジェクトが沢山あれば,具象クラスを共有するのと同じように,いつでもそれを共有できます.インタフェースやアダプタを具象クラスの近く(おそらくは,contrib サブディレクトリの中)にチェックインして,多くのプロジェクトにそれを利用してもらうことができます .. You need to weigh the pros and cons carefully for your particular problem, but I'd like to assure you that the Java community has been practicing this for a long time and it's a proven effective technique applicable in a wide variety of situations. :-) あなたの問題に対する利点と欠点を慎重に見極める必要があります.しかし,Java コミュニティでは長い間これが実践されており,さまざまな状況に適用できる効率的な手法であることが証明されている,ということは断言しておきましょう.:-) .. Delegating Calls to a Fake .. _cookbook_delegating_calls_to_a_fake: フェイクに呼び出しを委譲する ------------------------------------ .. Some times you have a non-trivial fake implementation of an interface. For example: インタフェースのフェイク実装が重要なものである場合があります.以下に例を示します. .. code-block:: c class Foo { public: virtual ~Foo() {} virtual char DoThis(int n) = 0; virtual void DoThat(const char* s, int* p) = 0; }; class FakeFoo : public Foo { public: virtual char DoThis(int n) { return (n > 0) ? '+' : (n < 0) ? '-' : '0'; } virtual void DoThat(const char* s, int* p) { *p = strlen(s); } }; .. Now you want to mock this interface such that you can set expectations on it. However, you also want to use FakeFoo for the default behavior, as duplicating it in the mock object is, well, a lot of work. さて,Expectation を設定できるようにこのインタフェースをモック化したい,とします.しかし,デフォルトの動作で FakeFoo も利用したいとなると,モックオブジェクト内でこれを再現することになり,作業が大変になります. .. When you define the mock class using Google Mock, you can have it delegate its default action to a fake class you already have, using this pattern: Google Mock を利用してモッククラスを定義する際,次のパターンを利用して,デフォルト Action を既存のフェイククラスに委譲することができます: .. code-block:: c using ::testing::_; using ::testing::Invoke; class MockFoo : public Foo { public: // Google Mock による通常のモックメソッド定義 MOCK_METHOD1(DoThis, char(int n)); MOCK_METHOD2(DoThat, void(const char* s, int* p)); // そのメソッドのデフォルト Action を FakeFoo オブジェクトに委譲します. // これは必ず,ON_CALL() 文よりも *前* に呼ばれる必要があります. void DelegateToFake() { ON_CALL(*this, DoThis(_)) .WillByDefault(Invoke(&fake_, &FakeFoo::DoThis)); ON_CALL(*this, DoThat(_, _)) .WillByDefault(Invoke(&fake_, &FakeFoo::DoThat)); } private: FakeFoo fake_; // フェイクのインスタンスをモック内部に保持しておきます. }; .. With that, you can use MockFoo in your tests as usual. Just remember that if you don't explicitly set an action in an ON_CALL() or EXPECT_CALL(), the fake will be called upon to do it: こうすると,テストコードで MockFoo をいつもどおり利用できます.ON_CALL() または EXPECT_CALL() で Action を明示的に指定しない場合,このフェイクが呼ばれることだけ考慮してください. .. code-block:: c using ::testing::_; TEST(AbcTest, Xyz) { MockFoo foo; foo.DelegateToFake(); // 委譲先のフェイクを有効にします. // 必要なら,ON_CALL(foo, ...) をここに. // Action が指定されない場合,このデフォルト Action が利用されることを意味します. EXPECT_CALL(foo, DoThis(5)); EXPECT_CALL(foo, DoThat(_, _)); int n = 0; EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() が呼び出されます. foo.DoThat("Hi", &n); // FakeFoo::DoThat() が呼び出されます. EXPECT_EQ(2, n); } .. Some tips: **ヒント:** .. If you want, you can still override the default action by providing your own ON_CALL() or using .WillOnce() / .WillRepeatedly() in EXPECT_CALL(). .. In DelegateToFake(), you only need to delegate the methods whose fake implementation you intend to use. .. The general technique discussed here works for overloaded methods, but you'll need to tell the compiler which version you mean. To disambiguate a mock function (the one you specify inside the parentheses of ON_CALL()), see the "Selecting Between Overloaded Functions" section on this page; to disambiguate a fake function (the one you place inside Invoke()), use a static_cast to specify the function's type. .. Having to mix a mock and a fake is often a sign of something gone wrong. Perhaps you haven't got used to the interaction-based way of testing yet. Or perhaps your interface is taking on too many roles and should be split up. Therefore, don't abuse this. We would only recommend to do it as an intermediate step when you are refactoring your code. * あなたが望むなら,ON_CALL() や EXPECT_CALL() 内で .WillOnce() / .WillRepeatedly() を使って,このデフォルト Action をオーバーライドすることもできます. * DelegataToFake() 内部で必要なことは,実際に使いたいフェイク実装にメソッドを委譲することだけです. * ここで議論される一般的なテクニックはオーバーロードされたメソッドに対しても動作しますが,どのバージョンを使うのかをコンパイラに教える必要があります.(ON_CALL() の丸カッコ内部で指定する)モック関数の曖昧さを解消するには,このページの「 :ref:`cookbook_selecting_overloaded_functions` 」のセクションを参照してください.また,(Invoke() 内に書く)フェイク関数の曖昧さを解消するには,static_cast を利用して関数の型を指定します. * モックとフェイクをミックスせざるを得ない状況は,何らかの不具合の表れである場合が多いです.おそらく,まだインタラクションに基づくテストのやり方に慣れていないのでしょう.あるいは,インタフェースに多くの役割がありすぎて,それを分割するべきなのかもしれません.そういうことなので, **この方法を乱用しないようにしてください** .コードをリファクタリングするときの中間段階としてのみ利用することをお勧めします. .. Regarding the tip on mixing a mock and a fake, here's an example on why it may be a bad sign: Suppose you have a class System for low-level system operations. In particular, it does file and I/O operations. And suppose you want to test how your code uses System to do I/O, and you just want the file operations to work normally. If you mock out the entire System class, you'll have to provide a fake implementation for the file operation part, which suggests that System is taking on too many roles. ヒントで述べたモックとフェイクを混ぜる話に関して,それがなぜ悪い兆候なのかを示す例を挙げます:ローレベルのシステム操作,具体的には,ファイル操作と I/O 操作を行う System クラスがあるとします.そして,I/O 操作を行うために System を利用しているコードのテストを行いたいとしましょう.このとき,ファイル操作に関しては,普通に動作すればよいものとします.ここで,System クラス全体をモック化すると,ファイル操作部分に関するフェイク実装を用意する必要が生じてしまいます.これは,System の役割が多すぎることを示唆しています. .. Instead, you can define a FileOps interface and an IOOps interface and split System's functionalities into the two. Then you can mock IOOps without mocking FileOps. 代わりに,FileOps インタフェースと IOOps インタフェースを定義し,System の機能を2つに分割する方法があります.すると,FileOps をモック化することなく,IOOps だけをモック化できます. .. Delegating Calls to a Real Object .. _cookbook_delegating_calls_to_a_real_object: 実際のオブジェクトに呼び出しを委譲する -------------------------------------------------- .. When using testing doubles (mocks, fakes, stubs, and etc), sometimes their behaviors will differ from those of the real objects. This difference could be either intentional (as in simulating an error such that you can test the error handling code) or unintentional. If your mocks have different behaviors than the real objects by mistake, you could end up with code that passes the tests but fails in production. テスト用の身代わり(モック,フェイク,スタブ,など)を利用する際,これらの動作が実際のオブジェクトと異なることがあります.この違いには,意図的な場合(エラーハンドリングコードのテストができるように,エラーをシミュレートしている場合など)と,そうではない場合があります.もし,手違いで,モックの挙動が実際のオブジェクトと違ってしまうと,テストをパスしたコードでも製品では失敗してしまうことが起こりえます. .. You can use the delegating-to-real technique to ensure that your mock has the same behavior as the real object while retaining the ability to validate calls. This technique is very similar to the delegating-to-fake technique, the difference being that we use a real object instead of a fake. Here's an example: delegating-to-real というテクニックを使うと,呼び出しの検証能力はそのままに,モックと実際のオブジェクトとが同じ挙動であることを保証できます.このテクニックは,delegating-to-fake テクニックと非常に似ており,その違いは,フェイクの代わりに実際のオブジェクトを使う点です.次に例を示します. .. code-block:: c using ::testing::_; using ::testing::AtLeast; using ::testing::Invoke; class MockFoo : public Foo { public: MockFoo() { // デフォルトでは,すべての呼び出しが,実際のオブジェクトに委譲されます. ON_CALL(*this, DoThis()) .WillByDefault(Invoke(&real_, &Foo::DoThis)); ON_CALL(*this, DoThat(_)) .WillByDefault(Invoke(&real_, &Foo::DoThat)); ... } MOCK_METHOD0(DoThis, ...); MOCK_METHOD1(DoThat, ...); ... private: Foo real_; }; ... MockFoo mock; EXPECT_CALL(mock, DoThis()) .Times(3); EXPECT_CALL(mock, DoThat("Hi")) .Times(AtLeast(1)); // ... テストでモックを利用 ... .. With this, Google Mock will verify that your code made the right calls (with the right arguments, in the right order, called the right number of times, etc), and a real object will answer the calls (so the behavior will be the same as in production). This gives you the best of both worlds. こうすることで,Google Mock が,あなたのコードの呼び出しが正しい(正しい引数を,正しい順番で,正しい回数,など)ことを検証し,実際のオブジェクトが,その呼び出しに答えます(よって,その動作は製品版と同じになります).これは,両者のいいとこどりです. .. Delegating Calls to a Parent Class .. _cookbook_delegating_calls_to_a_parent_class: 親クラスに呼び出しを委譲する --------------------------------------------------------------- .. Ideally, you should code to interfaces, whose methods are all pure virtual. In reality, sometimes you do need to mock a virtual method that is not pure (i.e, it already has an implementation). For example: 理想的には,インタフェースに対するコードを書くべきであり,そのメソッドはすべて純粋仮想関数であるはずです.しかし実際には,純粋仮想関数ではない仮想メソッド(つまり,すでに実装が存在するメソッド)をモック化する必要があります.以下に例を示します: .. code-block:: c class Foo { public: virtual ~Foo(); virtual void Pure(int n) = 0; virtual int Concrete(const char* str) { ... } }; class MockFoo : public Foo { public: // 純粋仮想メソッドのモック化. MOCK_METHOD1(Pure, void(int n)); // 具象メソッドのモック化.Foo::Concrete() is shadowed. MOCK_METHOD1(Concrete, int(const char* str)); }; .. Sometimes you may want to call Foo::Concrete() instead of MockFoo::Concrete(). Perhaps you want to do it as part of a stub action, or perhaps your test doesn't need to mock Concrete() at all (but it would be oh-so painful to have to define a new mock class whenever you don't need to mock one of its methods). 時には,MockFoo::Concrete() の代わりに Foo::Concrete() を呼び出したいことがあります.スタブ動作の一部としてそうしたいのかもしれないし,実はテストで Concrete() をモック化する必要が全くないのかもしれません(しかし,そのメソッドの1つをモック化する必要がないときでも,新しいモッククラスを定義しなければならないのは,あぁ,恐ろしいことです). .. The trick is to leave a back door in your mock class for accessing the real methods in the base class: このトリックを使うと,基底クラス内の実際のメソッドにアクセスする裏口をモックラスに残すことができます. .. code-block:: c class MockFoo : public Foo { public: // 純粋仮想メソッドのモック化. MOCK_METHOD1(Pure, void(int n)); // 具象メソッドのモック化.Foo::Concrete() is shadowed. MOCK_METHOD1(Concrete, int(const char* str)); // Foo で定義された ConCrete() を呼び出すには,これを使います. int FooConcrete(const char* str) { return Foo::Concrete(str); } }; .. Now, you can call Foo::Concrete() inside an action by: これで,次のようにして Action の内部で Foo::Concrete() を呼び出すことができます: .. code-block:: c using ::testing::_; using ::testing::Invoke; ... EXPECT_CALL(foo, Concrete(_)) .WillOnce(Invoke(&foo, &MockFoo::FooConcrete)); .. or tell the mock object that you don't want to mock Concrete(): また,Concrete() をモック化したくないモックオブジェクトを使うには次のようにします: .. code-block:: c using ::testing::Invoke; ... ON_CALL(foo, Concrete(_)) .WillByDefault(Invoke(&foo, &MockFoo::FooConcrete)); .. (Why don't we just write Invoke(&foo, &Foo::Concrete)? If you do that, MockFoo::Concrete() will be called (and cause an infinite recursion) since Foo::Concrete() is virtual. That's just how C++ works.) (どうして,単に Invoke(&foo, &Foo::Concrete) を書くだけではだめなのでしょうか?もしそうすると,Foo::Concrete() は仮想メソッドなので,MockFoo::Concrete() が呼び出されます(そして,無限再帰に陥ります).これは,単に C++ の仕様です.) .. Using Matchers .. _cookbook_using_matchers: Matcher を使う ============== .. Matching Argument Values Exactly .. _cookbook_matching_argument_values_exactly: 引数の値に対して厳密にマッチさせる --------------------------------------- .. You can specify exactly which arguments a mock method is expecting: モックメソッドが期待する引数を,厳密に指定することができます: .. code-block:: c using ::testing::Return; ... EXPECT_CALL(foo, DoThis(5)) .WillOnce(Return('a')); EXPECT_CALL(foo, DoThat("Hello", bar)); .. Using Simple Matchers .. _cookbook_using_simple_matchers: 単純な Matcher を利用する -------------------------------- .. You can use matchers to match arguments that have a certain property: matcher を利用して,ある条件を満たす引数にマッチすることができます: .. code-block:: c using ::testing::Ge; using ::testing::NotNull; using ::testing::Return; ... EXPECT_CALL(foo, DoThis(Ge(5))) // 引数は,必ず >= 5 .WillOnce(Return('a')); EXPECT_CALL(foo, DoThat("Hello", NotNull())); // 2番目の引数は,必ず NULL 以外. .. A frequently used matcher is _, which matches anything: よく使われる matcher は _ で,これは任意の入力にマッチします: .. code-block:: c using ::testing::_; using ::testing::NotNull; ... EXPECT_CALL(foo, DoThat(_, NotNull())); .. Combining Matchers .. _cookbook_combining_matchers: Matcher を組み合わせる --------------------------- .. You can build complex matchers from existing ones using AllOf(), AnyOf(), and Not(): AllOf(), AnyOf(), Not() を利用して,既存のものから複雑な matcher を構築できます: .. code-block:: c using ::testing::AllOf; using ::testing::Gt; using ::testing::HasSubstr; using ::testing::Ne; using ::testing::Not; ... // 引数は,必ず > 5 かつ != 10. EXPECT_CALL(foo, DoThis(AllOf(Gt(5), Ne(10)))); // 1番目の引数は,部分文字列として "blah" を含みません. EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), NULL)); .. Casting Matchers .. _cookbook_casting_matchers: Matcher をキャストする --------------------------- .. Google Mock matchers are statically typed, meaning that the compiler can catch your mistake if you use a matcher of the wrong type (for example, if you use Eq(5) to match a string argument). Good for you! Google Mock の matcher は,静的に型付けされているので,ユーザが間違った型の matcher を使っていると(例えば,Eq(5) を文字列型の引数にマッチさせようとした場合など),その間違いをコンパイラがキャッチできます.よかったですね! .. Sometimes, however, you know what you're doing and want the compiler to give you some slack. One example is that you have a matcher for long and the argument you want to match is int. While the two types aren't exactly the same, there is nothing really wrong with using a Matcher to match an int - after all, we can first convert the int argument to a long before giving it to the matcher. しかし時には,何をしているかを分かったうえで,コンパイラに見逃してほしい場合もあります.1つの例は,long に対する matcher があり,マッチさせたい引数が int の場合です.2つの型は厳密には等しくありませんが,Matcher を int にマッチさせても問題になることはありません.しかし結局は,matcher に渡す前にまず,int 型の引数を long に変換することになります. .. To support this need, Google Mock gives you the SafeMatcherCast(m) function. It casts a matcher m to type Matcher. To ensure safety, Google Mock checks that (let U be the type m accepts): この要求をサポートするために,Google Mock には, SafeMatcherCast(m) 関数が用意されています.これは,matcher m を Matcher 型にキャストします. 安全性を保証するため,Google Mock は,次のことをチェックします( U は m のとれる型とします): .. Type T can be implicitly cast to type U; .. When both T and U are built-in arithmetic types (bool, integers, and floating-point numbers), the conversion from T to U is not lossy (in other words, any value representable by T can also be represented by U); and .. When U is a reference, T must also be a reference (as the underlying matcher may be interested in the address of the U value). #. 型 T は,明示的に 型 U にキャスト可能. #. T と U が共に組み込みの算術型(ブール,整数,浮動小数点数)の場合,T から U への変換損失はない(別の言い方をすれば,T で表現される任意の値は, Uでも表現可能). #. U が参照の場合,T も必ず参照(内部的に利用される matcher が,U の値のアドレスを必要とするかもしれないので). .. The code won't compile if any of these conditions isn't met. これらの条件が満たされなければ,そのコードはコンパイルできません. .. Here's one example: 1つ例を示します: .. code-block:: c using ::testing::SafeMatcherCast; // 基底クラスと派生クラス. class Base { ... }; class Derived : public Base { ... }; class MockFoo : public Foo { public: MOCK_METHOD1(DoThis, void(Derived* derived)); }; ... MockFoo foo; // m は,どこかで作成済みの Matcher . EXPECT_CALL(foo, DoThis(SafeMatcherCast(m))); .. If you find SafeMatcherCast(m) too limiting, you can use a similar function MatcherCast(m). The difference is that MatcherCast works as long as you can static_cast type T to type U. SafeMatcherCast(m) の制限がきつすぎるならば,同様な関数 MatcherCast(m) を使うこともできます.MatcherCast は,型 T から型 U への static_cast が可能な場合に動作する,という点が異なります. .. MatcherCast essentially lets you bypass C++'s type system (static_cast isn't always safe as it could throw away information, for example), so be careful not to misuse/abuse it. MatcherCast は基本的に C++ の型システムへのバイパス(static_cast は 常に安全とは限りません.例えば,情報を捨てる可能性もあります)なので,間違って使ったり乱用したりしないように気を付けてください. .. Selecting Between Overloaded Functions .. _cookbook_selecting_overloaded_functions: オーバーロードされた関数の選択 -------------------------------------- .. If you expect an overloaded function to be called, the compiler may need some help on which overloaded version it is. オーバーロードされた関数の呼び出しを期待する場合,オーバーロードされたどのバージョンなのかをコンパイラが決めるために,助けが必要になるかもしれません. .. To disambiguate functions overloaded on the const-ness of this object, use the Const() argument wrapper. const な this オブジェクトで呼ばれるオーバーロードされた関数の曖昧さをなくすためには, Const() 引数ラッパーを利用します: .. code-block:: c using ::testing::ReturnRef; class MockFoo : public Foo { ... MOCK_METHOD0(GetBar, Bar&()); MOCK_CONST_METHOD0(GetBar, const Bar&()); }; ... MockFoo foo; Bar bar1, bar2; EXPECT_CALL(foo, GetBar()) // non-const GetBar() .WillOnce(ReturnRef(bar1)); EXPECT_CALL(Const(foo), GetBar()) // const GetBar() .WillOnce(ReturnRef(bar2)); .. (Const() is defined by Google Mock and returns a const reference to its argument.) (Const() は,Google Mock で定義されており,その引数の const な参照を返します.) .. To disambiguate overloaded functions with the same number of arguments but different argument types, you may need to specify the exact type of a matcher, either by wrapping your matcher in Matcher(), or using a matcher whose type is fixed (TypedEq, An(), etc): 引数の個数は同じで,引数の型が異なるようにオーバーロードされた関数の曖昧性をなくすには,matcher の正確な型を指定する必要があります.これには, Matcher() で matcher をラップするか,型が固定された matcher (TypedEq,An(),など)を使うかします. .. code-block:: c using ::testing::An; using ::testing::Lt; using ::testing::Matcher; using ::testing::TypedEq; class MockPrinter : public Printer { public: MOCK_METHOD1(Print, void(int n)); MOCK_METHOD1(Print, void(char c)); }; TEST(PrinterTest, Print) { MockPrinter printer; EXPECT_CALL(printer, Print(An())); // void Print(int); EXPECT_CALL(printer, Print(Matcher(Lt(5)))); // void Print(int); EXPECT_CALL(printer, Print(TypedEq('a'))); // void Print(char); printer.Print(3); printer.Print(6); printer.Print('a'); } .. Performing Different Actions Based on the Arguments .. _cookbook_performing_different_actions_based_on_the_arguments: 引数に応じて異なる Action を実行する ------------------------------------------------- .. When a mock method is called, the last matching expectation that's still active will be selected (think "newer overrides older"). So, you can make a method do different things depending on its argument values like this: モックメソッドが呼ばれると,最後にマッチした Expectation で,まだアクティブなものが選択されます(「新しいものが古いものに優先する」と考えてください).よって,引数の値に応じて動作が異なるメソッドを作ることができます. .. code-block:: c using ::testing::_; using ::testing::Lt; using ::testing::Return; ... // デフォルトの場合. EXPECT_CALL(foo, DoThis(_)) .WillRepeatedly(Return('b')); // より具体的な場合. EXPECT_CALL(foo, DoThis(Lt(5))) .WillRepeatedly(Return('a')); .. Now, if foo.DoThis() is called with a value less than 5, 'a' will be returned; otherwise 'b' will be returned. こうすることで,5 よりも小さい値が与えられた場合は foo.DoThis() が呼ばれ,「a」が返されます.そうでない場合は,「b」が返されます. .. Matching Multiple Arguments as a Whole .. _cookbook_matching_multiple_arguments_as_a_whole: 複数の引数全体にマッチングする -------------------------------------------- .. Sometimes it's not enough to match the arguments individually. For example, we may want to say that the first argument must be less than the second argument. The With() clause allows us to match all arguments of a mock function as a whole. For example, 個々の引数にマッチするだけでは不十分な場合があります.例えば,1番目の引数が2番目の引数よりも小さくなってほしい場合などです.With() 節を使うと,モック関数の全ての引数全体にマッチすることができます.以下に例を示します: .. code-block:: c using ::testing::_; using ::testing::Lt; using ::testing::Ne; ... EXPECT_CALL(foo, InRange(Ne(0), _)) .With(Lt()); .. says that the first argument of InRange() must not be 0, and must be less than the second argument. この場合,InRange() の1番目の引数は 0 以外の値で,かつ2番目の引数よりも小さくなければいけません. .. The expression inside With() must be a matcher of type Matcher >, where A1, ..., An are the types of the function arguments. With() 内部の式は,型 Matcher > の matcher となる必要があります.,ここで A1, ..., An は引数の型です. .. You can also write AllArgs(m) instead of m inside .With(). The two forms are equivalent, but .With(AllArgs(Lt())) is more readable than .With(Lt()). .With() の内部で,m の代わりに AllArgs(m) を使うこともできます.この2つの形式は等価ですが,With(AllArgs(Lt())) のほうが With(Lt()) よりも読みやすいでしょう. .. You can use Args(m) to match the n selected arguments (as a tuple) against m. For example, また,選択された n 個の引数(タプル)に対して Args(m) を使うことができます.例を示します: .. code-block:: c using ::testing::_; using ::testing::AllOf; using ::testing::Args; using ::testing::Lt; ... EXPECT_CALL(foo, Blah(_, _, _)) .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); .. says that Blah() will be called with arguments x, y, and z where x < y < z. この場合, x < y < z である引数 x,y,z で Blah() が呼び出されます. .. As a convenience and example, Google Mock provides some matchers for 2-tuples, including the Lt() matcher above. See the CheatSheet for the complete list. 便利なように,かつ手本として,Google Mock では,上述の Lt() matcher を含む 2-タプルに対する matcher がいくつか用意されています.完全な一覧は :ref:`cheatsheet` を参照してください. .. Note that if you want to pass the arguments to a predicate of your own (e.g. .With(Args<0, 1>(Truly(&MyPredicate)))), that predicate MUST be written to take a tr1::tuple as its argument; gMock will pass the n selected arguments as one single tuple to the predicate. 自分の述語関数に引数を渡したい場合(例えば, .With(Args<0, 1>(Truly(&MyPredicate))) ),その述語関数は必ず tr1::tuple を引数にとるようにしてください.gMock は n 個の選択された引数を 1つのタプルとして述語関数に渡します. .. Using Matchers as Predicates .. _cookbook_using_matchers_as_predicates: Matcher を述語関数として利用する ------------------------------------------ .. Have you noticed that a matcher is just a fancy predicate that also knows how to describe itself? Many existing algorithms take predicates as arguments (e.g. those defined in STL's header), and it would be a shame if Google Mock matchers are not allowed to participate. matcher は単に,自分自身の記述方法を知っている豪華な述語関数であることに気付きましたか?引数に述語関数をとるアルゴリズムがたくさん存在し(例えば,STL の ヘッダで定義されているものです),もし Google Mock の matcher がそこで使えなかったら,もったいないことです. .. Luckily, you can use a matcher where a unary predicate functor is expected by wrapping it inside the Matches() function. For example, 幸運なことに, matcher を Matches() 関数でラップすれば,1変数の述語ファンクタが期待されている場所で,それを利用することができます.次に例を示します: .. code-block:: c #include #include std::vector v; ... // v の要素数は >= 10 ? const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); .. Since you can build complex matchers from simpler ones easily using Google Mock, this gives you a way to conveniently construct composite predicates (doing the same using STL's header is just painful). For example, here's a predicate that's satisfied by any number that is >= 0, <= 100, and != 50: Google Mock では,単純なものを組み合わせて複雑な matcher を簡単に構築することができるので,これを使って,複合的な述語関数を都合に合わせて構成することができます(STL の ヘッダを使って同様のことをやるのは面倒なだけです).例えば以下は,0以上,100以下,かつ50ではないの任意の数によって満足できる述語関数の例です: .. code-block:: c Matches(AllOf(Ge(0), Le(100), Ne(50))) .. Using Matchers in Google Test Assertions .. _cookbook_using_matchers_in_gtest_assertions: Google Test アサーションで Matcher を利用する ----------------------------------------------------- .. Since matchers are basically predicates that also know how to describe themselves, there is a way to take advantage of them in Google Test assertions. It's called ASSERT_THAT and EXPECT_THAT: matcher は基本的に,自分自身の記述方法を知っている述語関数なので, `Google Test `_ アサーションでこれをうまく利用する方法があります.これは ASSERT_THAT と EXPECT_THAT と呼ばれます: .. code-block:: c ASSERT_THAT(value, matcher); // value が matcher にマッチすることをアサートします. EXPECT_THAT(value, matcher); // こちらは,致命的ではないバージョン. .. For example, in a Google Test test you can write: 例えば,Google Test で次のようにテストを書くことができます: .. code-block:: c #include "gmock/gmock.h" using ::testing::AllOf; using ::testing::Ge; using ::testing::Le; using ::testing::MatchesRegex; using ::testing::StartsWith; ... EXPECT_THAT(Foo(), StartsWith("Hello")); EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); .. which (as you can probably guess) executes Foo(), Bar(), and Baz(), and verifies that: これは,(おそらくあなたの想像通り)Foo(),Bar(),Baz() を実行して,以下のことを検証します: .. Foo() returns a string that starts with "Hello". .. Bar() returns a string that matches regular expression "Line \\d+". .. Baz() returns a number in the range 10. * Foo() が,"Hello" ではじまる文字列を返す. * Bar() が,正規表現 "Line \\d+" にマッチする文字列を返す. * Baz() が,5以上10以下の値を返す. .. The nice thing about these macros is that they read like English. They generate informative messages too. For example, if the first EXPECT_THAT() above fails, the message will be something like: 英語のように読めるのが,これらのマクロの良いところです.これらは,役立つメッセージも生成します.例えば,上述の最初の EXPECT_THAT() が失敗すると,次のようなメッセージが出力されます. :: Value of: Foo() Actual: "Hi, world!" Expected: starts with "Hello" .. Credit: The idea of (ASSERT|EXPECT)_THAT was stolen from the Hamcrest project, which adds assertThat() to JUnit. **クレジット:** (ASSERT|EXPECT)_THAT のアイディアは,JUnit に assertThat() を追加する `Hamcrest `_ プロジェクトから拝借しました. .. Using Predicates as Matchers .. _cookbook_using_predicates_as_matchers: 述語関数を Matcher として利用する -------------------------------------------- .. Google Mock provides a built-in set of matchers. In case you find them lacking, you can use an arbitray unary predicate function or functor as a matcher - as long as the predicate accepts a value of the type you want. You do this by wrapping the predicate inside the Truly() function, for example: Google Mock では,組み込みの matcher が複数用意されています.それでも足りない場合は,任意の1変数述語関数,またはファンクタを matcher をとして利用することができます.ただし,その述語関数は,あなたの望む型を受け取るものである必要があります.これは,述語関数を Truely() 関数でラップすることで可能になるもので,次に例を示します: .. code-block:: c using ::testing::Truly; int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } ... // Bar() は,必ず偶数の引数で呼び出されます. EXPECT_CALL(foo, Bar(Truly(IsEven))); .. Note that the predicate function / functor doesn't have to return bool. It works as long as the return value can be used as the condition in statement if (condition) .... この述語関数 / ファンクタは,bool を返す必要がないことに注意してください.戻り値が, if (条件) .... という文の中の条件として利用できるものであれば動作します. .. Matching Arguments that Are Not Copyable .. _cookbook_matching_arguments_that_are_not_copyable: コピーできない引数をマッチングする ------------------------------------------ .. When you do an EXPECT_CALL(mock_obj, Foo(bar)), Google Mock saves away a copy of bar. When Foo() is called later, Google Mock compares the argument to Foo() with the saved copy of bar. This way, you don't need to worry about bar being modified or destroyed after the EXPECT_CALL() is executed. The same is true when you use matchers like Eq(bar), Le(bar), and so on. EXPECT_CALL(mock_obj, Foo(bar)) とする場合, Google Mock は bar のコピーを保存しておきます.その後 Foo() が呼ばれ,Google Mock は,Foo() の引数と,保存された bar のコピーとを比較します.これにより,EXPECT_CALL() が実行された後の変更や破壊を心配する必要がなくなります.Eq(bar) や Le(bar) などの matcher を利用する場合も,この場合と同じです. .. But what if bar cannot be copied (i.e. has no copy constructor)? You could define your own matcher function and use it with Truly(), as the previous couple of recipes have shown. Or, you may be able to get away from it if you can guarantee that bar won't be changed after the EXPECT_CALL() is executed. Just tell Google Mock that it should save a reference to bar, instead of a copy of it. Here's how: しかし,bar がコピーできない(つまり,コピーコンストラクタをもたない)場合はどうなるのでしょう?前のレシピで述べたように,独自の matcher 関数をユーザが定義して,Truly() でラップして使う方法もあります.しかし,bar がEXPECT_CALL() の実行後も変更されないことを保証できれば,このようなことをせずに済みます.つまり単に,bar のコピーではなく参照を保存するように,Google Mock に命じるだけです.次に,やり方を示します: .. code-block:: c using ::testing::Eq; using ::testing::ByRef; using ::testing::Lt; ... // Foo() の引数 == bar であることを期待. EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar)))); // Foo() の引数 < bar であることを期待. EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar)))); .. Remember: if you do this, don't change bar after the EXPECT_CALL(), or the result is undefined. 注意:これを使う場合,EXPECT_CALL() の後で bar を変更しないでください.もし変更した場合の結果は未定義です. .. Validating a Member of an Object .. _cookbook_validating_a_member_of_an_object: オブジェクトのメンバを検証する ---------------------------------------- .. Often a mock function takes a reference to object as an argument. When matching the argument, you may not want to compare the entire object against a fixed object, as that may be over-specification. Instead, you may need to validate a certain member variable or the result of a certain getter method of the object. You can do this with Field() and Property(). More specifically, モック関数がオブジェクトの参照を引数にとることがよくあります.この引数のマッチングを行う場合,固定されたオブジェクト全体を比較するのはやり過ぎなので,そうしたくない場合があるかもしれません.代わりに,ある特定のメンバ変数や,オブジェクトのゲッターメソッドの結果を検証する必要がありそうです.このためには, Field() および Property() を使います.より具体的には,次のようになります. .. code-block:: c Field(&Foo::bar, m) .. is a matcher that matches a Foo object whose bar member variable satisfies matcher m. これは,そのメンバ bar が matcher m を満足するようなオブジェクト Foo にマッチする matcher です. .. code-block:: c Property(&Foo::baz, m) .. is a matcher that matches a Foo object whose baz() method returns a value that satisfies matcher m. これは,そのメソッド baz() の戻り値が matcher m を満足するようなオブジェクト Foo にマッチする matcher です. .. For example: 以下に例を示します: .. cvs-table:: :header: :widths: 20, 20 "Field(&Foo::number, Ge(3))", "x.number >= 3 である x にマッチします." "Property(&Foo::name, StartsWith(""John ""))", "x.names() が ""John "" で始まる x にマッチします." .. Note that in Property(&Foo::baz, ...), method baz() must take no argument and be declared as const. Property(&Foo::baz, ...) の中のメソッド baz() は引数をとらず,const として宣言されていなければいけないことに注意してください. .. BTW, Field() and Property() can also match plain pointers to objects. For instance, ところで,Field() と Property() は,オブジェクトを指す通常のポインタにもマッチできます.例えば,次のようになります. .. code-block:: c Field(&Foo::number, Ge(3)) .. matches a plain pointer p where p->number >= 3. If p is NULL, the match will always fail regardless of the inner matcher. これは,p->number >= 3 である通常のポインタ p にマッチします.p が NULL の場合,内部の matcher に関係なく,このマッチは常に失敗します. .. What if you want to validate more than one members at the same time? Remember that there is AllOf(). 同時に2つ以上のメンバを検証したい場合はどうするのでしょうか? AllOf() の存在を思い出してください. .. Validating the Value Pointed to by a Pointer Argument .. _cookbook_validating_the_value_pointed_to_by_a_pointer_argument: ポインタ引数に指される値を検証します ---------------------------------------------- .. C++ functions often take pointers as arguments. You can use matchers like NULL, NotNull(), and other comparison matchers to match a pointer, but what if you want to make sure the value pointed to by the pointer, instead of the pointer itself, has a certain property? Well, you can use the Pointee(m) matcher. C++ の関数は,よくポインタを引数にとります.そして,NULL,NotNull(),その他の比較 matcher といった,ポインタにマッチする matcher を利用できます.しかし,ポインタ自身ではなく,そのポインタに指されている値が特定のプロパティを持つことを確認したい場合はどうすればよいのでしょうか?そう, Pointee(m) matcher を利用できます. .. Pointee(m) matches a pointer iff m matches the value the pointer points to. For example: m がポインタの指す値にマッチした場合にのみ,Pointee(m) がポインタにマッチします.次に例を示します: .. code-block:: c using ::testing::Ge; using ::testing::Pointee; ... EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); .. expects foo.Bar() to be called with a pointer that points to a value greater than or equal to 3. foo.Bar() は,そのポインタの指す値が3以上であるようなポインタ,を引数として呼び出されることを期待されます. .. One nice thing about Pointee() is that it treats a NULL pointer as a match failure, so you can write Pointee(m) instead of Pointee() の良いところは,NULL ポインタをマッチ失敗として扱うので, .. code-block:: c AllOf(NotNull(), Pointee(m)) .. without worrying that a NULL pointer will crash your test. の代わりに,Pointee(m) と書いても,NULL ポインタがテストをクラッシュさせる心配がないところです. .. Also, did we tell you that Pointee() works with both raw pointers and smart pointers (linked_ptr, shared_ptr, scoped_ptr, and etc)? また,Pointee() は,通常のポインタとスマートポインタ(linked_ptr, shared_ptr, scoped_ptr など)のどちらに対しても動作します. .. What if you have a pointer to pointer? You guessed it - you can use nested Pointee() to probe deeper inside the value. For example, Pointee(Pointee(Lt(3))) matches a pointer that points to a pointer that points to a number less than 3 (what a mouthful...). ポインタを指すポインタの場合はどうなるのでしょう?より深い場所にある値を探索するために,Pointee() をネストして利用できます.例えば,Pointee(Pointee(Lt(3))) は,そのポインタの指すポインタの指す値(言いにくい…)が3よりも小さい場合にマッチします. .. Testing a Certain Property of an Object .. _cookbook_testing_a_certain_property_of_an_object: オブジェクトの特定のプロパティをテストする ------------------------------------------------- .. Sometimes you want to specify that an object argument has a certain property, but there is no existing matcher that does this. If you want good error messages, you should define a matcher. If you want to do it quick and dirty, you could get away with writing an ordinary function. 引数のオブジェクトが特定のプロパティを持つことを指定したい場合があります.しかし,そのようなことをする matcher は存在しません.分かりやすいエラーメッセージを望むならば,自分で matcher を定義するべきです.しかし,汚くても手早い方法でやりたいならば,通常の関数を書いて済ます方法もあります. .. Let's say you have a mock function that takes an object of type Foo, which has an int bar() method and an int baz() method, and you want to constrain that the argument's bar() value plus its baz() value is a given number. Here's how you can define a matcher to do it: あるモック関数が,型 Foo のオブジェクトを引数にとり,それが int bar() メソッドと int baz() メソッドを持つ場合に,bar() と gaz() の値の和に制約を設けたいとします.次のように matcher を定義することでこれが可能になります: .. code-block:: c using ::testing::MatcherInterface; using ::testing::MatchResultListener; class BarPlusBazEqMatcher : public MatcherInterface { public: explicit BarPlusBazEqMatcher(int expected_sum) : expected_sum_(expected_sum) {} virtual bool MatchAndExplain(const Foo& foo, MatchResultListener* listener) const { return (foo.bar() + foo.baz()) == expected_sum_; } virtual void DescribeTo(::std::ostream* os) const { *os << "bar() + baz() equals " << expected_sum_; } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "bar() + baz() does not equal " << expected_sum_; } private: const int expected_sum_; }; inline Matcher BarPlusBazEq(int expected_sum) { return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); } ... EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; .. Matching Containers .. _cookbook_matching_containers: コンテナをマッチングする -------------------------------- .. Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock function and you may want to validate it. Since most STL containers support the == operator, you can write Eq(expected_container) or simply expected_container to match a container exactly. モック関数に渡された STL コンテナ(例えば,list,vevtor,map,など)を検証したい場合があるかもしれません.大部分の STL コンテナは == 演算子をサポートしているので,Eq(expected_container) ,あるいは単に expected_container と書けば,コンテナとの厳密なマッチを行うことができます. .. Sometimes, though, you may want to be more flexible (for example, the first element must be an exact match, but the second element can be any positive number, and so on). Also, containers used in tests often have a small number of elements, and having to define the expected container out-of-line is a bit of a hassle. しかし,より柔軟な方法を必要とすることがあるかもしれません(例えば,最初の要素には厳密にマッチしたいが,2番目の要素は任意の正の数でかまわない,などといった場合です).また,テストでは少数要素のコンテナが使われる場合も多く,期待されるコンテナを余計に定義しなければならないのは少し面倒です. .. You can use the ElementsAre() matcher in such cases: このような場合,ElementsAre() matcher を利用することができます: .. code-block:: c using ::testing::_; using ::testing::ElementsAre; using ::testing::Gt; ... MOCK_METHOD1(Foo, void(const vector& numbers)); ... EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); .. The above matcher says that the container must have 4 elements, which must be 1, greater than 0, anything, and 5 respectively. この matcher は,コンテナが 4 要素を持ち,それぞれ 1 ,0より大きい,任意の数,5 ,となることを述べています. .. ElementsAre() is overloaded to take 0 to 10 arguments. If more are needed, you can place them in a C-style array and use ElementsAreArray() instead: ElementsAre() は,0 個から 10 個までの引数を取るようにオーバーロードされています.もっと多くの引数が必要な場合は,引数をC形式の配列に置き換えて,代わりに ElementsAreArray() を利用してください. .. code-block:: c using ::testing::ElementsAreArray; ... // ElementsAreArray は,要素値の配列を引数にとります. const int expected_vector1[] = { 1, 5, 2, 4, ... }; EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); // また,要素 matcher の配列も引数にとります. Matcher expected_vector2 = { 1, Gt(2), _, 3, ... }; EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); .. In case the array needs to be dynamically created (and therefore the array size cannot be inferred by the compiler), you can give ElementsAreArray() an additional argument to specify the array size: 動的に作成する必要がある配列(したがって,コンパイラがその配列サイズを推定できない)の場合,配列サイズを指定するための追加引数を ElementsAreArray() に渡すことができます: .. code-block:: c using ::testing::ElementsAreArray; ... int* const expected_vector3 = new int[count]; // ... expected_vector3 に値を代入します ... EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); .. Tips: **ヒント:** .. ElementAre*() works with any container that implements the STL iterator concept (i.e. it has a const_iterator type and supports begin()/end()) and supports size(), not just the ones defined in STL. It will even work with container types yet to be written - as long as they follows the above pattern. .. You can use nested ElementAre*() to match nested (multi-dimensional) containers. .. If the container is passed by pointer instead of by reference, just write Pointee(ElementsAre*(...)). .. The order of elements matters for ElementsAre*(). Therefore don't use it with containers whose element order is undefined (e.g. hash_map). * ElementAre*() は,たとえ STL で定義されているものではなくても,STL イテレータコンセプトが実装され(つまり,const_iterator 型を持ち, begin()/end() をサポートしている),size() をサポートする任意のコンテナに対して動作します.それどころか,前述のパターンに従う限り,まだ書かれていないコンテナ型に対しても動作します. * ネストした(多次元の)コンテナにマッチさせるために,ElementAre*() をネストさせて使うことができます. * コンテナを参照ではなくポインタで渡すには,単に Pointee(ElementsAre*(...)) と書くだけです. * ElementsAre*() にとって,要素の順番は重要な問題です.要素の順番が未定義なコンテナ(例えば,hash_map)に対しては,これを使用しないでください. .. Sharing Matchers .. _cookbook_sharing_matchers: Matcher を共有する ------------------------ .. Under the hood, a Google Mock matcher object consists of a pointer to a ref-counted implementation object. Copying matchers is allowed and very efficient, as only the pointer is copied. When the last matcher that references the implementation object dies, the implementation object will be deleted. 内部的には,Google Mock の matcher オブジェクトは,実装オブジェクトを指す参照カウント方式のポインタで構成されています.matcher のコピーは単なるポインタのコピーなので,非常に効率的です.実装オブジェクトを参照する最後の matcher が死ぬタイミングで,その実装オブジェクトは削除されます. .. Therefore, if you have some complex matcher that you want to use again and again, there is no need to build it everytime. Just assign it to a matcher variable and use that variable repeatedly! For example, したがって,ある複合 matcher を何度も繰り返し利用するつもりならば,それを毎回作成する必要はありません.matcher 変数に代入して,その変数を繰り返し使うだけで大丈夫です!以下に例を示します. .. code-block:: c Matcher in_range = AllOf(Gt(5), Le(10)); // ... 複数の EXPECT_CALL 内部で,in_range を matcher として利用します ... .. Setting Expectations .. _cookbook_setting_expectations: Expectation を設定する ==================== .. Ignoring Uninteresting Calls .. _cookbook_ignoring_uninteresting_calls: 関心がない呼び出しを無視する -------------------------------- .. If you are not interested in how a mock method is called, just don't say anything about it. In this case, if the method is ever called, Google Mock will perform its default action to allow the test program to continue. If you are not happy with the default action taken by Google Mock, you can override it using DefaultValue::Set() (described later in this document) or ON_CALL(). あるモックメソッドがどのように呼ばれるかに関心がなければ,まったく何もしないでください.この場合,そのメソッドが呼ばれると Google Mock は,テストプログラムを続行するためにデフォルト Action を実行します.Google Mock が実行するデフォルト Action では問題があるなら, DefaultValue::Set() (これについては後述します),または ON_CALL() を利用してそれを上書きすることができます. .. Please note that once you expressed interest in a particular mock method (via EXPECT_CALL()), all invocations to it must match some expectation. If this function is called but the arguments don't match any EXPECT_CALL() statement, it will be an error. ある特定のモックメソッドについて(EXPECT_CALL() を使って)何らかの指定を行うと,そのすべての呼び出しが,必ず何かの Expectation にマッチしなければいけないことに注意してください.この関数が, EXPECT_CALL() 文のいずれにもマッチしない引数で呼び出されると,エラーになります. .. Disallowing Unexpected Calls .. _cookbook_disallowing_unexpected_calls: 不要な呼び出しを許可しない ----------------------------------- .. If a mock method shouldn't be called at all, explicitly say so: モックメソッドが1度も呼び出されるべきものでないなら,次のように明示します: .. code-block:: c using ::testing::_; ... EXPECT_CALL(foo, Bar(_)) .Times(0); .. If some calls to the method are allowed, but the rest are not, just list all the expected calls: このメソッドの呼び出しの内,いくつかだけを許可して,残りは許可しない場合,期待するすべての呼び出しを表記します: .. code-block:: c using ::testing::AnyNumber; using ::testing::Gt; ... EXPECT_CALL(foo, Bar(5)); EXPECT_CALL(foo, Bar(Gt(10))) .Times(AnyNumber()); .. A call to foo.Bar() that doesn't match any of the EXPECT_CALL() statements will be an error. どの EXPECT_CALL() 文にもマッチしない foo.Bar() の呼び出しは,エラーになります. .. Expecting Ordered Calls .. _cookbook_expecting_ordered_calls: 順番通りの呼び出しを期待する ----------------------------------- .. Although an EXPECT_CALL() statement defined earlier takes precedence when Google Mock tries to match a function call with an expectation, by default calls don't have to happen in the order EXPECT_CALL() statements are written. For example, if the arguments match the matchers in the third EXPECT_CALL(), but not those in the first two, then the third expectation will be used. Google Mock が関数呼び出しを Expection にマッチさせようとする場合に,先に定義された EXPECT_CALL() 文が優先するとは言っても,デフォルトでは,EXPECT_CALL() 文が書かれた順番で関数呼び出しが起こる必要はありません.例えば引数が,1番目や2番目ではなく3番目の EXPECT_CALL() の matcher にマッチする場合,その3番目の Expectation が利用されます. .. If you would rather have all calls occur in the order of the expectations, put the EXPECT_CALL() statements in a block where you define a variable of type InSequence: 全ての呼び出しが Expectation の順番どおりに起こってほしいならば, InSequence 型の変数定義と同じブロック内に EXPECT_CALL() 文を置いてください. .. code-block:: c using ::testing::_; using ::testing::InSequence; { InSequence s; EXPECT_CALL(foo, DoThis(5)); EXPECT_CALL(bar, DoThat(_)) .Times(2); EXPECT_CALL(foo, DoThis(6)); } .. In this example, we expect a call to foo.DoThis(5), followed by two calls to bar.DoThat() where the argument can be anything, which are in turn followed by a call to foo.DoThis(6). If a call occurred out-of-order, Google Mock will report an error. この例では,foo.DoThis(5) の次に,任意の引数をとる bar.DoThat() が2回呼び出され,そして foo.DoThis(6) が呼び出される,という順番を期待しています.この順序で呼び出しが行われなかった場合,Google Mock はエラーをレポートします. .. Expecting Partially Ordered Calls .. _cookbook_expecting_partially_ordered_calls: 部分的に順番通りの呼び出しを期待する --------------------------------------------------- .. Sometimes requiring everything to occur in a predetermined order can lead to brittle tests. For example, we may care about A occurring before both B and C, but aren't interested in the relative order of B and C. In this case, the test should reflect our real intent, instead of being overly constraining. 全てが事前に定義した順番どおりに起こる必要があるとしたら,それはときに脆いテストになります.例えば,A が B と C よりも前に起こるようにしたいが,B と C の相対的な順番には関心がない,という場合を考えます.この場合テストに必要なのは,過剰な制約ではなく,我々の本当の意図を反映することです. .. Google Mock allows you to impose an arbitrary DAG (directed acyclic graph) on the calls. One way to express the DAG is to use the After clause of EXPECT_CALL. Google Mock では,呼び出しに対して,任意の DAG(directed acyclic graph:有向非巡回グラフ)を当てはめることができます. DAG を表現する方法の1つは,EXPECT_CALL で :ref:`After ` 節を利用することです. .. Another way is via the InSequence() clause (not the same as the InSequence class), which we borrowed from jMock 2. It's less flexible than After(), but more convenient when you have long chains of sequential calls, as it doesn't require you to come up with different names for the expectations in the chains. Here's how it works: また,もう1つの方法は,InSequence() 節(InSequence クラスとは異なります)を使うことで,これは jMock 2 から拝借しました.これは After() よりも柔軟性が低いですが,チェーン中の Expectations に応じた異なる名前を考えなくてもよいので,順序付いた長い呼び出しチェーンを書くときには便利な方法です.以下に例を示します: .. If we view EXPECT_CALL() statements as nodes in a graph, and add an edge from node A to node B wherever A must occur before B, we can get a DAG. We use the term "sequence" to mean a directed path in this DAG. Now, if we decompose the DAG into sequences, we just need to know which sequences each EXPECT_CALL() belongs to in order to be able to reconstruct the orginal DAG. EXPECT_CALL() 文をグラフのノードとみなし,A が B よりも前に起こらなければいけない場所すべてに,ノード A からノード B へのエッジを追加することで, DAG を記述できます.この DAG の有向パスの意味で,「シーケンス」という用語を使います.さて,DAG をシーケンスに分解した場合,元の DAG を再構成するためには,それぞれの EXPECT_CALL() がどのシーケンスに属するか,という情報だけが必要になります. .. So, to specify the partial order on the expectations we need to do two things: first to define some Sequence objects, and then for each EXPECT_CALL() say which Sequence objects it is part of. Expectations in the same sequence must occur in the order they are written. For example, したがって,Expectation の部分的な順番を指定するには,次の2点が必要になります:まず,Sequence オブジェクトを定義すること.そして,それぞれの EXPECT_CALL() が,どの Sequence オブジェクトに属するかを記述すること,です.同じシーケンスに属する複数の Expectation は,それらが書かれた順番通りに起こらなければいけません.次に例を示します. .. code-block:: c using ::testing::Sequence; Sequence s1, s2; EXPECT_CALL(foo, A()) .InSequence(s1, s2); EXPECT_CALL(bar, B()) .InSequence(s1); EXPECT_CALL(bar, C()) .InSequence(s2); EXPECT_CALL(foo, D()) .InSequence(s2); .. specifies the following DAG (where s1 is A -> B, and s2 is `A -> C -> D`): これは,次のような DAG(ここで s1 は A -> B,s2 は `A -> C -> D` を意味します)を表しています: :: +---> B | A ---| | +---> C ---> D .. This means that A must occur before B and C, and C must occur before D. There's no restriction about the order other than these. これは,A は B と C よりも前に,C は D よりも前に起きなければいけないことを意味しています.順番に関するそれ以外の制約はありません. .. Controlling When an Expectation Retires .. _cookbook_controlling_when_an_expectation_retires: Expectation の非アクティブ化を制御する ----------------------------------------------- .. When a mock method is called, Google Mock only consider expectations that are still active. An expectation is active when created, and becomes inactive (aka retires) when a call that has to occur later has occurred. For example, in モックメソッドが呼び出された際,Google Mock は,アクティブな Expectation のみを考慮します.Expectation は,作成された時点ではアクティブであり,自分より後に呼ばれるべきものが呼ばれた時点で非アクティブ(リタイアとも言います)になります.以下に例を示します. .. code-block:: c using ::testing::_; using ::testing::Sequence; Sequence s1, s2; EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 .Times(AnyNumber()) .InSequence(s1, s2); EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 .InSequence(s1); EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 .InSequence(s2); .. as soon as either #2 or #3 is matched, #1 will retire. If a warning "File too large." is logged after this, it will be an error. #2 または #3 にマッチしたらすぐに,#1 が非アクティブになります.その後に,"File too large." という警告が記録されると,エラーが発生します. .. Note that an expectation doesn't retire automatically when it's saturated. For example, Expectation が飽和しても,そこで自動的に非アクティブになるわけではないことに注意してください.次に例を示します. .. code-block:: c using ::testing::_; ... EXPECT_CALL(log, Log(WARNING, _, _)); // #1 EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 .. says that there will be exactly one warning with the message `"File too large."`. If the second warning contains this message too, #2 will match again and result in an upper-bound-violated error. これは,"File too large." というメッセージの警告が1度だけ起こることを想定しています.このメッセージの警告が2度起こると,2度目は #2 にマッチして,上限違反エラーが発生します. .. If this is not what you want, you can ask an expectation to retire as soon as it becomes saturated: これが望む動作ではない場合,Expectation が飽和した時点ですぐに非アクティブになるようにすることができます: .. code-block:: c using ::testing::_; ... EXPECT_CALL(log, Log(WARNING, _, _)); // #1 EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 .RetiresOnSaturation(); .. Here #2 can be used only once, so if you have two warnings with the message "File too large.", the first will match #2 and the second will match #1 - there will be no error. この場合,#2 は1度だけ利用されますので,"File too large." というメッセージの警告が2度起こると,最初の警告は #2 にマッチし,2度目の警告は #1 にマッチして,エラーは起こりません. .. Using Actions .. _cookbook_using_actions: Action を利用する =============== .. Returning References from Mock Methods .. _cookbook_returning_reference_from_mock_methods: モックメソッドから参照を返す --------------------------------- .. If a mock function's return type is a reference, you need to use ReturnRef() instead of Return() to return a result: モック関数の戻り値の型が参照の場合,結果を返すために,Retern() の代わりに ReturnRef() を使う必要があります: .. code-block:: c using ::testing::ReturnRef; class MockFoo : public Foo { public: MOCK_METHOD0(GetBar, Bar&()); }; ... MockFoo foo; Bar bar; EXPECT_CALL(foo, GetBar()) .WillOnce(ReturnRef(bar)); .. Returning Live Values from Mock Methods .. _cookbook_returnig_live_values_from_mock_methods: モックメソッドで,現在の値を返す ------------------------------------------------------ .. The Return(x) action saves a copy of x when the action is created, and always returns the same value whenever it's executed. Sometimes you may want to instead return the live value of x (i.e. its value at the time when the action is executed.). Return(x) という Action は,Action が作成されたときに x のコピーを保存します.そして,これが実行されたときは常に同じ値を返します.しかし,x の現在の値(つまり,Action が実行された時点での値)を返してほしい場合があるかもしれません. .. If the mock function's return type is a reference, you can do it using ReturnRef(x), as shown in the previous recipe ("Returning References from Mock Methods"). However, Google Mock doesn't let you use ReturnRef() in a mock function whose return type is not a reference, as doing that usually indicates a user error. So, what shall you do? 前のレシピ( :ref:`cookbook_returning_reference_from_mock_methods` )で述べたように,このモック関数の戻り値の型が参照の場合,ReternRef(x) とすれば可能です. しかし,Google Mockでは,戻り値の型が参照ではないモック関数の中で ReturnRef() を使うことはできないので,これはユーザエラーになります.では,どうすれば良いのでしょうか? .. You may be tempted to try ByRef(): ByRef() を試してみようと考えるかもしれません: .. code-block:: c using testing::ByRef; using testing::Return; class MockFoo : public Foo { public: MOCK_METHOD0(GetValue, int()); }; ... int x = 0; MockFoo foo; EXPECT_CALL(foo, GetValue()) .WillRepeatedly(Return(ByRef(x))); x = 42; EXPECT_EQ(42, foo.GetValue()); .. Unfortunately, it doesn't work here. The above code will fail with error: 残念ながら,これではうまく動きません.このコードは,エラーで失敗します: :: Value of: foo.GetValue() Actual: 0 Expected: 42 .. The reason is that Return(value) converts value to the actual return type of the mock function at the time when the action is created, not when it is executed. (This behavior was chosen for the action to be safe when value is a proxy object that references some temporary objects.) As a result, ByRef(x) is converted to an int value (instead of a const int&) when the expectation is set, and Return(ByRef(x)) will always return 0. これは,Action が実行され時点ではなく,作成された時点で,Return(value) が,値をモック関数の実際の戻り値型に変換するからです(値が一時オブジェクトを参照するプロキシオブジェクトであっても,安全に Action を実行できるように,このような挙動になっています). 結果として,Expectation が設定された時点で,ByRef(x) は(const int& ではなく)int 値に変換されます.そして,Return(ByRef(x)) は常に0を返します. .. ReturnPointee(pointer) was provided to solve this problem specifically. It returns the value pointed to by pointer at the time the action is executed: この問題に対処するために ReturnPointee(pointer) が用意されています.これは,Action が *実行された* 時点で,pointer に指されている値を返します: .. code-block:: c using testing::ReturnPointee; ... int x = 0; MockFoo foo; EXPECT_CALL(foo, GetValue()) .WillRepeatedly(ReturnPointee(&x)); // ここで & に注意してください. x = 42; EXPECT_EQ(42, foo.GetValue()); // これは,成功します. .. Combining Actions .. _cookbook_combining_actions: Action を組み合わせる ---------------------------- .. Want to do more than one thing when a function is called? That's fine. DoAll() allow you to do sequence of actions every time. Only the return value of the last action in the sequence will be used. ある関数が呼ばれたときに,2つ以上のことをしたいですか?いいでしょう.DoAll() を使えば,連続した Action を毎回実行できます.この場合,最後の Action の戻り値のみが利用されます. .. code-block:: c using ::testing::DoAll; class MockFoo : public Foo { public: MOCK_METHOD1(Bar, bool(int n)); }; ... EXPECT_CALL(foo, Bar(_)) .WillOnce(DoAll(action_1, action_2, ... action_n)); .. Mocking Side Effects .. _cookbook_mocking_side_effects: 副作用をモック化する ------------------------- .. Sometimes a method exhibits its effect not via returning a value but via side effects. For example, it may change some global state or modify an output argument. To mock side effects, in general you can define your own action by implementing ::testing::ActionInterface. メソッドによっては,戻り値ではなく副作用を介して,自分の効果を発揮するものがあります.例えば,グローバル状態を変えたり,出力引数を変更したりするようなものです.副作用をモック化するには,通常は,::testing::ActionInterface を実装して独自の Action を定義します. .. If all you need to do is to change an output argument, the built-in SetArgPointee() action is convenient: 出力変数を変更するだけで十分な場合,組み込みの SetArgPointee() Action を使うのが便利です: .. code-block:: c using ::testing::SetArgPointee; class MockMutator : public Mutator { public: MOCK_METHOD2(Mutate, void(bool mutate, int* value)); ... }; ... MockMutator mutator; EXPECT_CALL(mutator, Mutate(true, _)) .WillOnce(SetArgPointee<1>(5)); .. In this example, when mutator.Mutate() is called, we will assign 5 to the int variable pointed to by argument #1 (0-based). この例では,mutator.Mutate() が呼ばれると,#1 (0基準)の引数 で指された int 変数に 5 を代入します. .. SetArgPointee() conveniently makes an internal copy of the value you pass to it, removing the need to keep the value in scope and alive. The implication however is that the value must have a copy constructor and assignment operator. SetArgPointee() は,渡された値の内部的なコピーを作成しますので,スコープ内で値を有効な状態に保っておく必要がなくなります.しかし,この実装では,値がコピーコンストラクタおよび代入演算子をサポートしている必要があります. .. If the mock method also needs to return a value as well, you can chain SetArgPointee() with Return() using DoAll(): モックメソッドが戻り値も必要とする場合,SetArgPointee() と Return() を DoAll() でつなげることができます: .. code-block:: c using ::testing::_; using ::testing::Return; using ::testing::SetArgPointee; class MockMutator : public Mutator { public: ... MOCK_METHOD1(MutateInt, bool(int* value)); }; ... MockMutator mutator; EXPECT_CALL(mutator, MutateInt(_)) .WillOnce(DoAll(SetArgPointee<0>(5), Return(true))); .. If the output argument is an array, use the SetArrayArgument(first, last) action instead. It copies the elements in source range [first, last) to the array pointed to by the N-th (0-based) argument: 出力引数が配列の場合,代わりに SetArrayArgument(first, last) Action を利用してください.これは,入力範囲 [first, last) の要素を,N-番目(0基準)の引数が指す配列にコピーします: .. code-block:: c using ::testing::NotNull; using ::testing::SetArrayArgument; class MockArrayMutator : public ArrayMutator { public: MOCK_METHOD2(Mutate, void(int* values, int num_values)); ... }; ... MockArrayMutator mutator; int values[5] = { 1, 2, 3, 4, 5 }; EXPECT_CALL(mutator, Mutate(NotNull(), 5)) .WillOnce(SetArrayArgument<0>(values, values + 5)); .. This also works when the argument is an output iterator: これは,引数が出力イテレータの場合でも動作します: .. code-block:: c using ::testing::_; using ::testing::SeArrayArgument; class MockRolodex : public Rolodex { public: MOCK_METHOD1(GetNames, void(std::back_insert_iterator >)); ... }; ... MockRolodex rolodex; vector names; names.push_back("George"); names.push_back("John"); names.push_back("Thomas"); EXPECT_CALL(rolodex, GetNames(_)) .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); .. Changing a Mock Object's Behavior Based on the State .. _cookbook_changing_a_mock_objects_behavior_based_on_the_state: モックオブジェクトの状態に応じて挙動を変える ----------------------------------------------------------------------- .. If you expect a call to change the behavior of a mock object, you can use ::testing::InSequence to specify different behaviors before and after the call: モックオブジェクトの挙動を変更する関数呼び出しをテストしたい場合,その呼び出しの前後で別の挙動を指定するには, ::testing::InSequence を利用します. .. code-block:: c using ::testing::InSequence; using ::testing::Return; ... { InSequence seq; EXPECT_CALL(my_mock, IsDirty()) .WillRepeatedly(Return(true)); EXPECT_CALL(my_mock, Flush()); EXPECT_CALL(my_mock, IsDirty()) .WillRepeatedly(Return(false)); } my_mock.FlushIfDirty(); .. This makes my_mock.IsDirty() return true before my_mock.Flush() is called and return false afterwards. この場合,my_mock.IsDirty() は,my_mock.Flush() が呼ばれる前は true を返し,呼ばれた後は false を返します. .. If the behavior change is more complex, you can store the effects in a variable and make a mock method get its return value from that variable: 挙動の変化がより複雑な場合は,効果を変数に保存しておき,モックメソッドの戻り値が,その変数の値になるようにします: .. code-block:: c using ::testing::_; using ::testing::SaveArg; using ::testing::Return; ACTION_P(ReturnPointee, p) { return *p; } ... int previous_value = 0; EXPECT_CALL(my_mock, GetPrevValue()) .WillRepeatedly(ReturnPointee(&previous_value)); EXPECT_CALL(my_mock, UpdateValue(_)) .WillRepeatedly(SaveArg<0>(&previous_value)); my_mock.DoSomethingToUpdateValue(); .. Here my_mock.GetPrevValue() will always return the argument of the last UpdateValue() call. この場合,my_mock.GetPrevValue() は,直前の UpdateValue() の引数の値を常に返します. .. Setting the Default Value for a Return Type .. _cookbook_setting_the_default_value_for_a_return_type: ある戻り値型に対するデフォルト値を設定する -------------------------------------------------------------- .. If a mock method's return type is a built-in C++ type or pointer, by default it will return 0 when invoked. You only need to specify an action if this default value doesn't work for you. モックメソッドの戻り値の型が組み込みの C++ 型やポインタならば,実行時にはデフォルトで 0 を返します.このデフォルト値では不十分な場合のみ,Action を指定する必要があります. .. Sometimes, you may want to change this default value, or you may want to specify a default value for types Google Mock doesn't know about. You can do this using the ::testing::DefaultValue class template: このデフォルト値を変更したり,Google Mock が知らない型のデフォルト値を指定したりすることが必要な場合も考えられます. ::testing::DefaultValue クラステンプレートを利用すれば,これが可能です. .. code-block:: c class MockFoo : public Foo { public: MOCK_METHOD0(CalculateBar, Bar()); }; ... Bar default_bar; // デフォルトの Bar 型リターン値 をセットします. DefaultValue::Set(default_bar); MockFoo foo; // デフォルトのリターン値があるので, // ここで Action を指定する必要はありません. EXPECT_CALL(foo, CalculateBar()); foo.CalculateBar(); // これは default_bar を返すはず. // デフォルトのリターン値を外します. DefaultValue::Clear(); .. Please note that changing the default value for a type can make you tests hard to understand. We recommend you to use this feature judiciously. For example, you may want to make sure the Set() and Clear() calls are right next to the code that uses your mock. ある型のデフォルト値を変更すると,テストの可読性が下がることには注意してください.これは,注意して使う機能であることを忘れないでください.例えば,モックを利用するコードのすぐ隣で Set() と Clear() を呼び出すようにしてください. .. Setting the Default Actions for a Mock Method .. _cookbook_setting_the_default_actions_for_a_mock_method: モックメソッドのデフォルト Action を設定する ----------------------------------------------------------- .. You've learned how to change the default value of a given type. However, this may be too coarse for your purpose: perhaps you have two mock methods with the same return type and you want them to have different behaviors. The ON_CALL() macro allows you to customize your mock's behavior at the method level: ある型のデフォルト値を変更する方法は既に学びました.しかし,やりたい事を実現するには,これだけでは不足かもしれません:同じ戻り値型を持つ2つのモックメソッドがあり,それぞれに異なった動作をさせたい場合などです. ON_CALL() マクロを使えば,メソッドレベルでモックの動作をカスタマイズすることができます. .. code-block:: c using ::testing::_; using ::testing::AnyNumber; using ::testing::Gt; using ::testing::Return; ... ON_CALL(foo, Sign(_)) .WillByDefault(Return(-1)); ON_CALL(foo, Sign(0)) .WillByDefault(Return(0)); ON_CALL(foo, Sign(Gt(0))) .WillByDefault(Return(1)); EXPECT_CALL(foo, Sign(_)) .Times(AnyNumber()); foo.Sign(5); // これは, 1 を返します. foo.Sign(-9); // これは, -1 を返します. foo.Sign(0); // これは, 0 を返します. .. As you may have guessed, when there are more than one ON_CALL() statements, the news order take precedence over the older ones. In other words, the last one that matches the function arguments will be used. This matching order allows you to set up the common behavior in a mock object's constructor or the test fixture's set-up phase and specialize the mock's behavior later. あなたの推測どおり,1つ以上の ON_CALL() 文がある箇所では,新しいものが古いものを上書きします.別の言い方をすれば,関数の引数に最後にマッチしたものが利用されます.このようなマッチング順序があるおかげで,モックオブジェクトのコンストラクタやテストフィクスチャの set-up 内で共通の動作をセットし,後からモックの動作を個別に指定することができます. .. Using Functions/Methods/Functors as Actions .. _cookbook_using_functions_methods_functors_as_actions: 関数/メソッド/ファンクタを Action として利用する ----------------------------------------------------------------- .. If the built-in actions don't suit you, you can easily use an existing function, method, or functor as an action: 組み込みの Action では不足な場合,既存の関数,メソッド,ファンクタを Action として簡単に利用することができます: .. code-block:: c using ::testing::_; using ::testing::Invoke; class MockFoo : public Foo { public: MOCK_METHOD2(Sum, int(int x, int y)); MOCK_METHOD1(ComplexJob, bool(int x)); }; int CalculateSum(int x, int y) { return x + y; } class Helper { public: bool ComplexJob(int x); }; ... MockFoo foo; Helper helper; EXPECT_CALL(foo, Sum(_, _)) .WillOnce(Invoke(CalculateSum)); EXPECT_CALL(foo, ComplexJob(_)) .WillOnce(Invoke(&helper, &Helper::ComplexJob)); foo.Sum(5, 6); // CalculateSum(5, 6) を呼び出します. foo.ComplexJob(10); // helper.ComplexJob(10) を呼び出します. .. The only requirement is that the type of the function, etc must be compatible with the signature of the mock function, meaning that the latter's arguments can be implicitly converted to the corresponding arguments of the former, and the former's return type can be implicitly converted to that of the latter. So, you can invoke something whose type is not exactly the same as the mock function, as long as it's safe to do so - nice, huh? ここで必要なのは,呼び出す関数の型などが,モック関数のシグネチャと互換性があることです.つまり,後者の引数が対応する前者の引数に暗黙に型変換可能で,前者の戻り値型が後者のそれに暗黙に型変換可能である,という意味です.これが安全に行える限り,モック関数と型が異なるものでも呼び出すことができます.どう?いいでしょ? .. Invoking a Function/Method/Functor Without Arguments .. _cookbook_invoking_a_function_method_functor_without_arguments: 関数/メソッド/ファンクタを引数なしで呼び出す ------------------------------------------------------------ .. Invoke() is very useful for doing actions that are more complex. It passes the mock function's arguments to the function or functor being invoked such that the callee has the full context of the call to work with. If the invoked function is not interested in some or all of the arguments, it can simply ignore them. Invoke() は,より複雑な Action を実行するのにはとても便利です.この場合,モック関数の引数が呼び出し対象の関数やファンクタに渡されるので,呼び出しの完全なコンテキストを把握した上で動作します.もし呼び出される関数にとって,一部または全部の引数が不要な場合,それらを簡単に無視することができます. .. Yet, a common pattern is that a test author wants to invoke a function without the arguments of the mock function. Invoke() allows her to do that using a wrapper function that throws away the arguments before invoking an underlining nullary function. Needless to say, this can be tedious and obscures the intent of the test. しかし,テストを書く側は皆,モック関数の引数を使わずに関数を呼び出したい,と考えます.内部の引数なし関数を呼び出す前に,引数を捨ててしまうようなラッパ関数を使えば,Invoke() でそれを実現することができます.言うまでもないことですが,この方法はつまらないですし,テストの意図を不明瞭にしてしまう可能性があります. .. InvokeWithoutArgs() solves this problem. It's like Invoke() except that it doesn't pass the mock function's arguments to the callee. Here's an example: InvokeWithoutArgs() は,この問題を解決します.これは,モック関数の引数を,呼び出される関数に渡さないことを除いて,Invoke() と同じです.次に例を示します: .. code-block:: c using ::testing::_; using ::testing::InvokeWithoutArgs; class MockFoo : public Foo { public: MOCK_METHOD1(ComplexJob, bool(int n)); }; bool Job1() { ... } ... MockFoo foo; EXPECT_CALL(foo, ComplexJob(_)) .WillOnce(InvokeWithoutArgs(Job1)); foo.ComplexJob(10); // Job1() を呼び出します. .. Invoking an Argument of the Mock Function .. _cookbook_invoking_an_argument_of_the_mock_function: モック関数の引数を呼び出す ------------------------------------- .. Sometimes a mock function will receive a function pointer or a functor (in other words, a "callable") as an argument, e.g. モック関数の引数として,関数ポインタやファンクタ(別の言い方をすれば,"callable")を受け取る場合があります.例えば,次のような例です. .. code-block:: c class MockFoo : public Foo { public: MOCK_METHOD2(DoThis, bool(int n, bool (*fp)(int))); }; .. and you may want to invoke this callable argument: この呼び出し可能な引数を,次のように呼び出したいと考えるでしょう: .. code-block:: c using ::testing::_; ... MockFoo foo; EXPECT_CALL(foo, DoThis(_, _)) .WillOnce(...); // (*fp)(5) を実行します.ここで,fp は // DoThis() の2番目の引数です. .. Arghh, you need to refer to a mock function argument but C++ has no lambda (yet), so you have to define your own action. :-( Or do you really? ここで,モック関数の引数を参照する必要がありますが,C++ には(まだ)ラムダ式がないので,自分で Action を定義する必要があります.:-( えっ,本当に? .. Well, Google Mock has an action to solve exactly this problem: Google Mock には,まさにこの問題を解決するための Action が用意されています. :: InvokeArgument(arg_1, arg_2, ..., arg_m) .. will invoke the N-th (0-based) argument the mock function receives, with arg_1, arg_2, ..., and arg_m. No matter if the argument is a function pointer or a functor, Google Mock handles them both. これは,モック関数が受け取る N-番目(0基準)の実行可能な引数に,arg_1,arg_2,...,arg_m を渡して呼び出します.引数が関数ポインタやファンクタのどちらでも,Google Mock は扱うことができます. .. With that, you could write: これを使うと,次のように書くことができます: .. code-block:: c using ::testing::_; using ::testing::InvokeArgument; ... EXPECT_CALL(foo, DoThis(_, _)) .WillOnce(InvokeArgument<1>(5)); // (*fp)(5) を実行します.ここで,fp は // DoThis() の2番目の引数です. .. What if the callable takes an argument by reference? No problem - just wrap it inside ByRef(): callable の引数が参照型の場合はどうでしょう?問題ありません - ByRef() でラップするだけです: .. code-block:: c ... MOCK_METHOD1(Bar, bool(bool (*fp)(int, const Helper&))); ... using ::testing::_; using ::testing::ByRef; using ::testing::InvokeArgument; ... MockFoo foo; Helper helper; ... EXPECT_CALL(foo, Bar(_)) .WillOnce(InvokeArgument<0>(5, ByRef(helper))); // ByRef(helper) は,helper のコピーではなく,参照が // callable に渡されることを保証します. .. What if the callable takes an argument by reference and we do not wrap the argument in ByRef()? Then InvokeArgument() will make a copy of the argument, and pass a reference to the copy, instead of a reference to the original value, to the callable. This is especially handy when the argument is a temporary value: では,callable の引数が参照の場合に,その引数を ByRef() でラップ **しなかった** らどうなるでしょうか?InvokeArgument() は,引数の *コピーを作成し* ,元の値への参照ではなく *コピーへの参照* を callable へ渡します.これは特に,引数が一時的な値である場合に便利です. .. code-block:: c ... MOCK_METHOD1(DoThat, bool(bool (*f)(const double& x, const string& s))); ... using ::testing::_; using ::testing::InvokeArgument; ... MockFoo foo; ... EXPECT_CALL(foo, DoThat(_)) .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); // (*f)(5.0, string("Hi")) を実行します.ここで,f は DoThat が受け取った // 関数ポインタです.値 5.0 と string("Hi") は,一時的なもので, // EXPECT_CALL() 文が終了した際に同時に無効になることに注意してください. // しかし,これらの値のコピーが InvokeArgument Action 内部に保存されているので, // 後からこの Action を実行しても大丈夫です. .. Ignoring an Action's Result .. _cookbook_ignoring_an_actions_result: Action の結果を無視する ------------------------------ .. Sometimes you have an action that returns something, but you need an action that returns void (perhaps you want to use it in a mock function that returns void, or perhaps it needs to be used in DoAll() and it's not the last in the list). IgnoreResult() lets you do that. For example: *何か* を返す Action があるけれど,実は void を返す Action が必要という場合があります(void を返すモック関数の内で使いたいのかもしれませんし,DoAll() の中の最後以外の場所で利用されるのかもしれません).IgnoreResult() を使えば,それが可能になります.以下に例を示します: .. code-block:: c using ::testing::_; using ::testing::Invoke; using ::testing::Return; int Process(const MyData& data); string DoSomething(); class MockFoo : public Foo { public: MOCK_METHOD1(Abc, void(const MyData& data)); MOCK_METHOD0(Xyz, bool()); }; ... MockFoo foo; EXPECT_CALL(foo, Abc(_)) // .WillOnce(Invoke(Process)); // Abc() は void の戻り値が必要なのに,Process() が int を返すので, // 上の行はコンパイルできません. .WillOnce(IgnoreResult(Invoke(Process))); EXPECT_CALL(foo, Xyz()) .WillOnce(DoAll(IgnoreResult(Invoke(DoSomething)), // DoSomething() が返す文字列を無視します. Return(true))); .. Note that you cannot use IgnoreResult() on an action that already returns void. Doing so will lead to ugly compiler errors. 元から void を返す Action の中では IgnoreResult() を利用できないことに注意してください.もし,これをすると,ひどいコンパイルエラーが起こります. .. Selecting an Action's Arguments .. _cookbook_selecting_an_actions_arguments: Action の引数を選択する -------------------------------- .. Say you have a mock function Foo() that takes seven arguments, and you have a custom action that you want to invoke when Foo() is called. Trouble is, the custom action only wants three arguments: 7つの引数をとるモック関数 Foo() と,その Foo() が呼ばれたときに呼び出したいカスタム Action があるとしましょう.ここで問題なのは,そのカスタム Action が 3つの引数しか必要としないことです: .. code-block:: c using ::testing::_; using ::testing::Invoke; ... MOCK_METHOD7(Foo, bool(bool visible, const string& name, int x, int y, const map, double>& weight, double min_weight, double max_wight)); ... bool IsVisibleInQuadrant1(bool visible, int x, int y) { return visible && x >= 0 && y >= 0; } ... EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) .WillOnce(Invoke(IsVisibleInQuadrant1)); // うーん,コンパイルできない.:-( .. To please the compiler God, you can to define an "adaptor" that has the same signature as Foo() and calls the custom action with the right arguments: コンパイラ様を満足させるには,Foo() と同じシグネチャを持ち,内部でカスタム Action を呼び出すような「アダプタ」を定義します: .. code-block:: c using ::testing::_; using ::testing::Invoke; bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, const map, double>& weight, double min_weight, double max_wight) { return IsVisibleInQuadrant1(visible, x, y); } ... EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // 今度は動作します. .. But isn't this awkward? でも,これってカッコ悪いですよね? .. Google Mock provides a generic action adaptor, so you can spend your time minding more important business than writing your own adaptors. Here's the syntax: Google Mock には,一般的な *Action アダプタ* が用意されていますので,独自のアダプタを書く事よりも重要な仕事に注力できます.以下が,その構文です: :: WithArgs(action) .. creates an action that passes the arguments of the mock function at the given indices (0-based) to the inner action and performs it. Using WithArgs, our original example can be written as: これは,指定されたインデックス(0基準)で表現されるモック関数の引数を,内部の Action に渡して実行するような Action を作成します.WithArgs を使うと,元々の例は次のように書くことができます: .. code-block:: c using ::testing::_; using ::testing::Invoke; using ::testing::WithArgs; ... EXPECT_CALL(mock, Foo(_, _, _, _, _, _, _)) .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); // 独自のアダプタを定義する必要はありません. .. For better readability, Google Mock also gives you: さらに読みやすくするために,Google Mock には次のようなものが用意されています: .. WithoutArgs(action) when the inner action takes no argument, and .. WithArg(action) (no s after Arg) when the inner action takes one argument. * 内部の Action が引数を取らない場合に利用できる,WithoutArgs(action) . * 内部の Action が引数を1つ取る場合に利用できる,WithArg(action) (Arg の後の s はナシ ). .. As you may have realized, InvokeWithoutArgs(...) is just syntactic sugar for WithoutArgs(Inovke(...)). 気づいたかもしれませんが,InvokeWithoutArgs(...) は,単に WithoutArgs(Inovke(...)) のシンタックスシュガーです. .. Here are more tips: ヒントをいくつか書いておきましょう: .. The inner action used in WithArgs and friends does not have to be Invoke() -- it can be anything. .. You can repeat an argument in the argument list if necessary, e.g. WithArgs<2, 3, 3, 5>(...). .. You can change the order of the arguments, e.g. WithArgs<3, 2, 1>(...). .. The types of the selected arguments do not have to match the signature of the inner action exactly. It works as long as they can be implicitly converted to the corresponding arguments of the inner action. For example, if the 4-th argument of the mock function is an int and my_action takes a double, WithArg<4>(my_action) will work. * WithArgs とその仲間で利用される内部 Action は,必ずしも Invoke() される必要はありません.-- これは,何であっても問題ありません. * 必要ならば,例えば, WithArgs<2, 3, 3, 5>(...) というように,引数リストの引数を繰り返し使うことができます. * 例えば,WithArgs<3, 2, 1>(...) というように,引数の順番を変更することができます. * 選択された引数の型が,内部 Action のシグネチャに厳密に一致する必要はありません.内部 Action の対応する引数に,暗黙に型変換できれば動作します.例えば,モック関数の4番目の引数が int で,my_action が double を取る場合でも,WithArg<4>(my_action) は動作します. .. Ignoring Arguments in Action Functions .. _cookbook_ignoring_arguments_in_action_functions: Action 関数の引数を無視する ------------------------------------- .. The selecting-an-action's-arguments recipe showed us one way to make a mock function and an action with incompatible argument lists fit together. The downside is that wrapping the action in WithArgs<...>() can get tedious for people writing the tests. Action の引数の選択に関するレシピでは,モック関数と Action で,互換性のない引数リストを互いに適合させる方法を学びました.これの欠点は,Action を WtihArgs<...>() でラップするのが,テストを書く人にとって面倒かもしれないことです. .. If you are defining a function, method, or functor to be used with Invoke*(), and you are not interested in some of its arguments, an alternative to WithArgs is to declare the uninteresting arguments as Unused. This makes the definition less cluttered and less fragile in case the types of the uninteresting arguments change. It could also increase the chance the action function can be reused. For example, given Invoke*() で利用される関数,メソッド,ファンクタを定義する際,いくつかの引数が不要な場合,WithArgs に代わる方法は,不要な引数を利用しないものとして宣言することです.これにより,定義が簡潔になり,そして不要な引数の型が変更された場合も影響を受けずに済みます.また,Action 関数を再利用する機会が増加する可能性もあります.では,次に例を示します. .. code-block:: c MOCK_METHOD3(Foo, double(const string& label, double x, double y)); MOCK_METHOD3(Bar, double(int index, double x, double y)); .. instead of これが,与えられている場合, .. code-block:: c using ::testing::_; using ::testing::Invoke; double DistanceToOriginWithLabel(const string& label, double x, double y) { return sqrt(x*x + y*y); } double DistanceToOriginWithIndex(int index, double x, double y) { return sqrt(x*x + y*y); } ... EXEPCT_CALL(mock, Foo("abc", _, _)) .WillOnce(Invoke(DistanceToOriginWithLabel)); EXEPCT_CALL(mock, Bar(5, _, _)) .WillOnce(Invoke(DistanceToOriginWithIndex)); .. you could write 上記のような書き方の代わりに,次のように書くことができます. .. code-block:: c using ::testing::_; using ::testing::Invoke; using ::testing::Unused; double DistanceToOrigin(Unused, double x, double y) { return sqrt(x*x + y*y); } ... EXEPCT_CALL(mock, Foo("abc", _, _)) .WillOnce(Invoke(DistanceToOrigin)); EXEPCT_CALL(mock, Bar(5, _, _)) .WillOnce(Invoke(DistanceToOrigin)); .. Sharing Actions .. _cookbook_sharing_actions: Action を共有する ----------------------- .. Just like matchers, a Google Mock action object consists of a pointer to a ref-counted implementation object. Therefore copying actions is also allowed and very efficient. When the last action that references the implementation object dies, the implementation object will be deleted. Google Mock の Action オブジェクトは,丁度 matcher と同様に,参照カウント方式の実装オブジェクトへのポインタで構成されています.したがって,Action は効率的にコピーすることが可能です.実装オブジェクトを参照する最後の Action が死ぬと,その実装オブジェクトは削除されます. .. If you have some complex action that you want to use again and again, you may not have to build it from scratch everytime. If the action doesn't have an internal state (i.e. if it always does the same thing no matter how many times it has been called), you can assign it to an action variable and use that variable repeatedly. For example: 複雑な Action を何度も再利用したい場合,毎回それを最初から作成する必要はないかもしれません.その Action が内部状態を持たない場合(つまり,呼び出された回数にかかわらず常に同じ動作をする場合),それを Action 変数に代入し,その変数を繰り返し使います.次に例を示します: .. code-block:: c Action set_flag = DoAll(SetArgPointee<0>(5), Return(true)); // ... .WillOnce() と .WillRepeatedly() の内部で set_flag を利用します ... .. However, if the action has its own state, you may be surprised if you share the action object. Suppose you have an action factory IncrementCounter(init) which creates an action that increments and returns a counter whose initial value is init, using two actions created from the same expression and using a shared action will exihibit different behaviors. Example: しかし,Action が自身の状態を持っている場合,その Action を共有すると予期しない事が起こる可能性があります.Action ファクトリ IncrementCounter(init) があり,これは,初期値が init であるカウンタ値を増加させて,それを返す Action を生成するとします.同じ式から作られた2つの Action を利用する場合と,共有 Action を利用する場合では,違う挙動を示します.例を示しましょう: .. when .. code-block:: c EXPECT_CALL(foo, DoThis()) .WillRepeatedly(IncrementCounter(0)); EXPECT_CALL(foo, DoThat()) .WillRepeatedly(IncrementCounter(0)); foo.DoThis(); // 1 を返す. foo.DoThis(); // 2 を返す. foo.DoThat(); // 1 を返す. Blah() と Bar() は, // 違うカウンタを利用します. .. versus これに対して,次のようになります. .. code-block:: c Action increment = IncrementCounter(0); EXPECT_CALL(foo, DoThis()) .WillRepeatedly(increment); EXPECT_CALL(foo, DoThat()) .WillRepeatedly(increment); foo.DoThis(); // 1 を返す. foo.DoThis(); // 2 を返す. foo.DoThat(); // 3 を返す.カウンタは共有されます. .. Misc Recipes on Using Google Mock .. _cookbook_misc_recipes_on_using_gmook: Google Mock を利用したその他のレシピ =================================== .. Forcing a Verification .. _cookbook_forcing_a_varification: 強制的に検証を行う --------------------------- .. When it's being destoyed, your friendly mock object will automatically verify that all expectations on it have been satisfied, and will generate Google Test failures if not. This is convenient as it leaves you with one less thing to worry about. That is, unless you are not sure if your mock object will be destoyed. モックオブジェクトが破壊されると,あなたのモックオブジェクトは,すべての Expectation が満足されていたかどうか検証し,そうでなければ Google Test の失敗を生成します.これは,あなたの心配事をとりあえず1つ減らしてくれる便利な機能です.つまり,モックオブジェクトが破壊されるかどうかが分からない場合は,やっぱり心配だということですが. .. How could it be that your mock object won't eventually be destroyed? Well, it might be created on the heap and owned by the code you are testing. Suppose there's a bug in that code and it doesn't delete the mock object properly - you could end up with a passing test when there's actually a bug. モックオブジェクトが破壊されなかった場合はどうなるのでしょうか?例えば,あなたがテストしているコードがモックオブジェクトをヒープ上に作って持っているかもしれません.そのコードにバグがあり,モックオブジェクトを適切に削除しないとすると,実際にはバグがある箇所のテストをパスしてしまうことになります. .. Using a heap checker is a good idea and can alleviate the concern, but its implementation may not be 100% reliable. So, sometimes you do want to force Google Mock to verify a mock object before it is (hopefully) destructed. You can do this with Mock::VerifyAndClearExpectations(&mock_object): ヒープチェッカーを使うのは良い考えですし,多少なりとも心配が減りますが,その実装が100%信用できるものとは限りません.そういうわけで,Google Mock が モックオブジェクトを,(できれば)それが破壊される前に強制的に検証して欲しい場合があります. Mock::VerifyAndClearExpectations(&mock_object) を使えば,それが可能になります. .. code-block:: c TEST(MyServerTest, ProcessesRequest) { using ::testing::Mock; MockFoo* const foo = new MockFoo; EXPECT_CALL(*foo, ...)...; // ... その他の Expectation ... // server が foo を所有しています. MyServer server(foo); server.ProcessRequest(...); // server のデストラクタが foo を削除し忘れた場合に備えて, // これは,とにかく Expectation を検証します. Mock::VerifyAndClearExpectations(foo); } // このスコープから外れると server が破壊されます. .. Tip: The Mock::VerifyAndClearExpectations() function returns a bool to indicate whether the verification was successful (true for yes), so you can wrap that function call inside a ASSERT_TRUE() if there is no point going further when the verification has failed. **ヒント:** Mock::VerifyAndClearExpectations() 関数は,検証が成功した(その場合は,true )かどうかを示す bool 値を返します.よって,検証が失敗した場合にそれ以上処理を続けない場合は,その関数呼び出しを ASSERT_TRUE() でラップします. .. Using Check Points .. _cookbook_using_check_points: チェクポイントを利用する ------------------------------- .. Sometimes you may want to "reset" a mock object at various check points in your test: at each check point, you verify that all existing expectations on the mock object have been satisfied, and then you set some new expectations on it as if it's newly created. This allows you to work with a mock object in "phases" whose sizes are each manageable. テストにおける様々なチェックポイントで,モックオブジェクトを「リセット」したい場合があります:各チェックポイントでは,モックオブジェクトに存在するすべての Expectation が満足されていることを検証し,もし新しく作られた Expectation があれば,それをセットします.これによって,モックオブジェクトを「段階的」に動作させ,それぞれのサイズを個々に管理することができます. .. One such scenario is that in your test's SetUp() function, you may want to put the object you are testing into a certain state, with the help from a mock object. Once in the desired state, you want to clear all expectations on the mock, such that in the TEST_F body you can set fresh expectations on it. このような状況は,テストの SetUp() 関数の中で起こり得ます.例えば,現在テストしているオブジェクトを,ある状態にして,その状態になった後は,TEST_F の中に新しい Expectatioin をセットできるように,モックのすべての Expectation をクリアしたい,といった状況が考えられます. .. As you may have figured out, the Mock::VerifyAndClearExpectations() function we saw in the previous recipe can help you here. Or, if you are using ON_CALL() to set default actions on the mock object and want to clear the default actions as well, use Mock::VerifyAndClear(&mock_object) instead. This function does what Mock::VerifyAndClearExpectations(&mock_object) does and returns the same bool, plus it clears the ON_CALL() statements on mock_object too. お気づきかもしれませんが,前のレシピで見た Mock::VerifyAndClearExpectations() 関数が,ここでも役に立ちます.もし,ON_CALL() を利用してモックオブジェクトのデフォルトの Action をセットしており,それをクリアするために同様に ON_CALL() を利用しようとしているならば,代わりに Mock::VerifyAndClear(&mock_object) を使ってください.この関数は, Mock::VerifyAndClearExpectations(&mock_object) と同じ事を行い,同じ bool 値を返します. **さらに** ,モックオブジェクトの ON_CALL() 文のクリアも行います. .. Another trick you can use to achieve the same effect is to put the expectations in sequences and insert calls to a dummy "check-point" function at specific places. Then you can verify that the mock function calls do happen at the right time. For example, if you are exercising code: 同じ効果を得るためのもう1つの方法は,シーケンス内に Expectation を配置し,ダミーの「チェックポイント」関数呼び出しを特定の場所に挿入することです.そうすると,モック関数が適切な時点で呼び出されていることを検証できます.例えば,次のようなコードを実行するとしましょう: .. code-block:: c Foo(1); Foo(2); Foo(3); .. and want to verify that Foo(1) and Foo(3) both invoke mock.Bar("a"), but Foo(2) doesn't invoke anything. You can write: そして, Foo(1) と Foo(3) は共に mock.Bar("a") を呼び出すが Foo(2) は何も呼び出さない,ということを検証したいとします.これは,次のように書けます: .. code-block:: c using ::testing::MockFunction; TEST(FooTest, InvokesBarCorrectly) { MyMock mock; // MockFunction クラスは,1つのメソッドだけを持ちます. // それは Call() という名前で,戻り値型は F です. MockFunction check; { InSequence s; EXPECT_CALL(mock, Bar("a")); EXPECT_CALL(check, Call("1")); EXPECT_CALL(check, Call("2")); EXPECT_CALL(mock, Bar("a")); } Foo(1); check.Call("1"); Foo(2); check.Call("2"); Foo(3); } .. The expectation spec says that the first Bar("a") must happen before check point "1", the second Bar("a") must happen after check point "2", and nothing should happen between the two check points. The explicit check points make it easy to tell which Bar("a") is called by which call to Foo(). この Expectation は,最初の Bar("a") は必ずチェックポイント "1" よりも前に起こる,2番目の Bar("a") は必ずチェックポイント "2" よりも後に起こる,そして2つのチェックポイントの間では何も起こらない,ということを規定しています.チェックポイントを明示することで,どの Foo() 呼び出しによって,どの Bar("a") が呼び出されるのかが分かりやすくなります. .. Mocking Destructors .. _cookbook_mocking_destructors: デストラクタをモック化する ------------------------------------- .. Sometimes you want to make sure a mock object is destructed at the right time, e.g. after bar->A() is called but before bar->B() is called. We already know that you can specify constraints on the order of mock function calls, so all we need to do is to mock the destructor of the mock function. モックオブジェクトが適切な時期,例えば bar->A() が呼ばれた後で bar->B() が呼ばれる前,に確実にデストラクトされるようにしたい場合があります.モック関数の呼び出し順序を指定する方法を既に知っていますので,必要なのは,モック関数のデストラクタをモック化する事だけです. .. This sounds simple, except for one problem: a destructor is a special function with special syntax and special semantics, and the MOCK_METHOD0 macro doesn't work for it: これは簡単に思えますが,1つ問題があります:デストラクタは,特別な構文を持ち特別な動作を行う特殊な関数で,MOCK_METHOD0 マクロではうまくいかないという点です: .. code-block:: c MOCK_METHOD0(~MockFoo, void()); // コンパイルできない! .. The good news is that you can use a simple pattern to achieve the same effect. First, add a mock function Die() to your mock class and call it in the destructor, like this: 幸いなことに,簡単なパターンを使って同じことができます.以下のように,まずモッククラスにモック関数 Die() を追加し,デストラクタでそれを呼び出します: .. code-block:: c class MockFoo : public Foo { ... // モッククラスに次の2行を追加します. MOCK_METHOD0(Die, void()); virtual ~MockFoo() { Die(); } }; .. (If the name Die() clashes with an existing symbol, choose another name.) Now, we have translated the problem of testing when a MockFoo object dies to testing when its Die() method is called: (もし,Die() という名前が既にあるシンボルと衝突する場合は,別の名前にしてください.)そして,MockFoo オブジェクトが死んだ場合のテスト,という問題を,Die() メソッドが呼び出された場合のテスト,に置き換えます. .. code-block:: c MockFoo* foo = new MockFoo; MockBar* bar = new MockBar; ... { InSequence s; // bar->A() の後,bar->B() の前で *foo が死ぬことを期待. EXPECT_CALL(*bar, A()); EXPECT_CALL(*foo, Die()); EXPECT_CALL(*bar, B()); } .. And that's that. これだけです. .. Using Google Mock and Threads .. _cookbook_using_gmock_and_threads: Google Mock とスレッドを使う ----------------------------------------------------- .. IMPORTANT NOTE: What we describe in this recipe is ONLY true on platforms where Google Mock is thread-safe. Currently these are only platforms that support the pthreads library (this includes Linux and Mac). To make it thread-safe on other platforms we only need to implement some synchronization operations in "gtest/internal/gtest-port.h". **重要な注意:** このレシピで述べることは,Google Mock がスレッドセーフであるプラットフォーム **のみ** において正しいものです.これは現在のところ,pthreads ライブラリをサポートするプラットフォーム(Linux や Mac)に限られます.その他のプラットフォームにおいてスレッドセーフを実現するには, "gtest/internal/gtest-port.h" に同期操作を実装する必要があります. .. In a unit test, it's best if you could isolate and test a piece of code in a single-threaded context. That avoids race conditions and dead locks, and makes debugging your test much easier. 単体テストにおいて,コードを部分的に分離し,シングルスレッドなコンテキストでテストできるならば,それがベストです.そうすることで,競合状態やデッドロックを避け,テストのデバッグが非常に簡単になります. .. Yet many programs are multi-threaded, and sometimes to test something we need to pound on it from more than one thread. Google Mock works for this purpose too. しかし,多くのプログラムはマルチスレッド化されており,場合によっては,何らかのテストを行うために1つ以上のスレッドからそれをたたく必要があります.Google Mock は,この目的でも利用されます. .. Remember the steps for using a mock: モックを利用するステップを思い出してください: .. Create a mock object foo. .. Set its default actions and expectations using ON_CALL() and EXPECT_CALL(). .. The code under test calls methods of foo. .. Optionally, verify and reset the mock. .. Destroy the mock yourself, or let the code under test destroy it. The destructor will automatically verify it. #. モックオブジェクトを作成します. #. ON_CALL() および EXPECT_CALL() を用いて,デフォルト Action と Expectation をセットします. #. テストコードから foo の メソッドを呼び出します. #. オプションとして,モックの検証とリセットを行います. #. 自分でモックを破棄するか,テストコードに破棄させるか,します.デストラクタは,自動的にそれを検証します. .. If you follow the following simple rules, your mocks and threads can live happily togeter: 次の簡単なルールを守れば,モックとスレッドの利用は楽しく共存できます: .. Execute your test code (as opposed to the code being tested) in one thread. This makes your test easy to follow. .. Obviously, you can do step #1 without locking. .. When doing step #2 and #5, make sure no other thread is accessing foo. Obvious too, huh? .. #3 and #4 can be done either in one thread or in multiple threads - anyway you want. Google Mock takes care of the locking, so you don't have to do any - unless required by your test logic. * テストコードは(テストされているコードとは逆に),1つのスレッドで実行してください.これで,テストを追いかけやすくなります. * ステップ #1 をロックせずに行えるのは,明らかです. * ステップ #2 と #5 実行時に,他のスレッドが foo にアクセスしないようにします.これも明らか,ですよね? * #3 と #4 は,1つのスレッドでも複数のスレッドでも,望む方で動作可能です.ロック は Google Mock が対処するので,あなたのテストロジックが必要としない限り,何する必要がありません. .. If you violate the rules (for example, if you set expectations on a mock while another thread is calling its methods), you get undefined behavior. That's not fun, so don't do it. このルールを破った場合(例えば,他のスレッドが,モックメソッドを呼んでいる最中に,そのモックに Expectation をセットする)の動作は未定義です.まぁ,楽しいものではないので,破らないようにしてください. .. Google Mock guarantees that the action for a mock function is done in the same thread that called the mock function. For example, in Google Mock は,モック関数の Action が,そのモック関数を呼び出したのと同一のスレッドで実行されることを保証します.次に例を示します. .. code-block:: c EXPECT_CALL(mock, Foo(1)) .WillOnce(action1); EXPECT_CALL(mock, Foo(2)) .WillOnce(action2); .. if Foo(1) is called in thread 1 and Foo(2) is called in thread 2, Google Mock will execute action1 in thread 1 and action2 in thread 2. スレッド 1 で Foo(1) が呼ばれ,スレッド 2 で Foo(2) が呼ばれると,Google Mock は,スレッド 1 で action1 を実行し,スレッド 2 で action2 を実行します. .. Google Mock does not impose a sequence on actions performed in different threads (doing so may create deadlocks as the actions may need to cooperate). This means that the execution of action1 and action2 in the above example may interleave. If this is a problem, you should add proper synchronization logic to action1 and action2 to make the test thread-safe. Google Mock では,異なるスレッドで実行される Action がシーケンスのように連続して実行されるという制約はありません(これはデッドロックを起こす可能性があるので,Action 同士の協調が必要になるかもしれません).つまり,上述のサンプルにおける action1 と action2 の実行が,交互に起こるかもしれないという意味です.これが問題ならば,テストをスレッドセーフにするために,action1 と action2 に適切な同期ロジックを追加してください. .. Also, remember that DefaultValue is a global resource that potentially affects all living mock objects in your program. Naturally, you won't want to mess with it from multiple threads or when there still are mocks in action. また,DefaultValue は,プログラム内のすべてのモックオブジェクトに影響を与える可能性のあるグローバルリソースだという事を思い出してください.当然,これを複数のスレッドから扱ったり,実行中のモックが存在する瞬間に操作したりしないようにしてください. .. Controlling How Much Information Google Mock Prints .. _cookbook_controlling_how_much_information_gmock_prints: Google Mock が出力する情報の量を制御する ------------------------------------------------------ .. When Google Mock sees something that has the potential of being an error (e.g. a mock function with no expectation is called, a.k.a. an uninteresting call, which is allowed but perhaps you forgot to explicitly ban the call), it prints some warning messages, including the arguments of the function and the return value. Hopefully this will remind you to take a look and see if there is indeed a problem. Google Mock は,潜在的にエラーになるかもしれない何か(例えば,Expectation がないモック関数が呼ばれること,つまり,不要な呼び出しがその例です.これは可能ですが,その呼び出しを明示的に禁止するのを忘れた可能性もあります)を見つけると,その関数の引数と戻り値を含む警告メッセージを表示します.これを見れば,それが実際に問題にならないかどうかを確認する気になるかもしれません. .. Sometimes you are confident that your tests are correct and may not appreciate such friendly messages. Some other times, you are debugging your tests or learning about the behavior of the code you are testing, and wish you could observe every mock call that happens (including argument values and the return value). Clearly, one size doesn't fit all. あるときは,あなたは自分のテストの正しさに自信があり,このような親切なメッセージに価値を認めないかもしれません.別のあるときは,テストをデバッグしている際や,テストしているコードの動作を調べている際に,発生している各モックの呼び出し(そして,その引数と戻り値)を監視したい場合があるかもしれません.万能な設定がないのは明らかです. .. You can control how much Google Mock tells you using the --gmock_verbose=LEVEL command-line flag, where LEVEL is a string with three possible values: コマンドラインフラグ --- gmock_verbose=LEVEL を用いて,Google Mock が出力する情報の量を制御することができます.ここで LEVEL は,以下の3つの値を取ることができます: .. info: Google Mock will print all informational messages, warnings, and errors (most verbose). At this setting, Google Mock will also log any calls to the ON_CALL/EXPECT_CALL macros. .. warning: Google Mock will print both warnings and errors (less verbose). This is the default. .. error: Google Mock will print errors only (least verbose). * info:Google Mock は,全ての情報を含むメッセージ,警告,エラーを出力します(最も詳細).この設定ではさらに,Google Mock が ON_CALL/EXPECT_CALL マクロの全ての呼び出しを記録します. * warning:Google Mock は,警告とエラーを出力します(やや詳細).これがデフォルトです. * error:Google Mock は,エラーのみを出力します(詳細ではない). .. Alternatively, you can adjust the value of that flag from within your tests like so: 別の方法として,次のように,テスト内部でこのフラグの値を設定することもできます: .. code-block:: c ::testing::FLAGS_gmock_verbose = "error"; .. Now, judiciously use the right flag to enable Google Mock serve you better! では,Google Mock をより役立てられるように,正しいフラグを賢く使ってください. .. Running Tests in Emacs .. _cookbook_running_tests_in_emacs: Emacs でテストを実行する ----------------------------- .. If you build and run your tests in Emacs, the source file locations of Google Mock and Google Test errors will be highlighted. Just press on one of them and you'll be taken to the offending line. Or, you can just type C-x ` to jump to the next error. Emacs でテストを書いて実行すると,ソースファイルでの Google Mock と Google Test のエラーの場所が強調表示されます.その1つを選択して を押すだけで,問題の行に移動します.また,C-x とタイプすると,次のエラーにジャンプします. .. To make it even easier, you can add the following lines to your ~/.emacs file: これをさらに簡単にするには,あなたの ~/.emacs ファイルに,次の行を追加してください: :: (global-set-key "\M-m" 'compile) ; m is for make (global-set-key [M-down] 'next-error) (global-set-key [M-up] '(lambda () (interactive) (next-error -1))) .. Then you can type M-m to start a build, or M-up/M-down to move back and forth between errors. M-m でビルド開始,M-up/M-down で前後のエラーに移動します. .. Fusing Google Mock Source Files .. _cookbook_fusing_gmock_source_files: Google Mock のソースファイルを統合する ------------------------------------------------ .. Google Mock's implementation consists of dozens of files (excluding its own tests). Sometimes you may want them to be packaged up in fewer files instead, such that you can easily copy them to a new machine and start hacking there. For this we provide an experimental Python script fuse_gmock_files.py in the scripts/ directory (starting with release 1.2.0). Assuming you have Python 2.4 or above installed on your machine, just go to that directory and run Google Mock の実装は,(それ自身のテストを含む)数ダースのファイルから構成されています.新しいマシンに簡単にコピーして使うために,これらをより少ないファイルにまとめたい場合があります.scripts/ ディレクトリに,このための実験的な Python スクリプト fuse_gmock_files.py を用意しています(バージョン 1.2.0 以降).マシンに Python 2.4 以降がインストールされていれば,そのディレクトリに移動して,次のように実行 :: python fuse_gmock_files.py OUTPUT_DIR .. and you should see an OUTPUT_DIR directory being created with files gtest/gtest.h, gmock/gmock.h, and gmock-gtest-all.cc in it. These three files contain everything you need to use Google Mock (and Google Test). Just copy them to anywhere you want and you are ready to write tests and use mocks. You can use the scrpts/test/Makefile file as an example on how to compile your tests against them. すると,OUTPUT_DIR ディレクトリに,gtest/gtest.h と gmock/gmock.h,gmock-gtest-all.cc が作成されているはずです.これらのファイルには,Google Mock(および Google Test) を使うためのすべてが含まれています.これらを好きな場所にコピーするだけで,テストを書いてモックを使う準備が整います.これを使ってテストをコンパイルする例として,ファイル `scripts/test/Makefile `_ が参考になります. .. Extending Google Mock .. _cookbook_extending_gmock: Google Mock を拡張する ====================== .. Writing New Matchers Quickly .. _cookbook_writing_new_matchers_quickly: 新規の Matcher を簡単に書く ------------------------------------- .. The MATCHER* family of macros can be used to define custom matchers easily. The syntax: MATCHER* 形式のマクロを使って,カスタム matcher を簡単に定義することができます.構文は,次のようになります: .. code-block:: c MATCHER(name, description_string_expression) { statements; } .. will define a matcher with the given name that executes the statements, which must return a bool to indicate if the match succeeds. Inside the statements, you can refer to the value being matched by arg, and refer to its type by arg_type. これは,statements を実行する,name という名の matcher を定義します.これは,マッチに成功したか否かを示す bool 値を返さなければいけません. statements の中では,マッチされる値を arg で,その型を arg_type で参照できます. .. The description string is a string-typed expression that documents what the matcher does, and is used to generate the failure message when the match fails. It can (and should) reference the special bool variable negation, and should evaluate to the description of the matcher when negation is false, or that of the matcher's negation when negation is true. 説明文字列は,matcher が何をするかを示す文字列型の式であり,マッチ失敗時の失敗メッセージを生成するのに利用されます.これは,特別な bool 変数 negation を参照できます(そして,ぜひ参照すべきです).negation が false であれば matcher を説明し,negation が true であれば matcher の否定を説明するようにします. .. For convenience, we allow the description string to be empty (""), in which case Google Mock will use the sequence of words in the matcher name as the description. 便利のよいように,説明文字列には空文字 ("") を指定できます.この場合,Google Mock は matcher の名前を構成する一連の文字を説明文として利用します. .. For example: 例えば: .. code-block:: c MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } .. allows you to write とすれば,次のように書くことができます. .. code-block:: c // n が 7 の倍数の場合に mock_foo.Bar(n) が呼ばれることを期待します. EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); .. or, または, .. code-block:: c using ::testing::Not; ... EXPECT_THAT(some_expression, IsDivisibleBy7()); EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); .. If the above assertions fail, they will print something like: 上記のアサーションが失敗すると,次のようなメッセージが出力されます: :: Value of: some_expression Expected: is divisible by 7 Actual: 27 ... Value of: some_other_expression Expected: not (is divisible by 7) Actual: 21 .. where the descriptions "is divisible by 7" and `"not (is divisible by 7)"` are automatically calculated from the matcher name IsDivisibleBy7. この "is divisible by 7" および "not (is divisible by 7)" という説明文は,matcher 名の IsDivisibleBy7 から自動的に作られるものです. .. As you may have noticed, the auto-generated descriptions (especially those for the negation) may not be so great. You can always override them with a string expression of your own: お気づきのように,自動生成された説明文(特に,否定に対しての文)は,特に優れているというわけではありません.自分の文字列式で,いつでもこれらを上書きできます. .. code-block:: c MATCHER(IsDivisibleBy7, std::string(negation ? "isn't" : "is") + " divisible by 7") { return (arg % 7) == 0; } .. Optionally, you can stream additional information to a hidden argument named result_listener to explain the match result. For example, a better definition of IsDivisibleBy7 is: オプションとして,マッチ結果を説明するための result_listener という名前の隠れ引数に,追加情報を流し込むことができます.例えば,IsDivisibleBy7 のより良い定義は: .. code-block:: c MATCHER(IsDivisibleBy7, "") { if ((arg % 7) == 0) return true; *result_listener << "the remainder is " << (arg % 7); return false; } .. With this definition, the above assertion will give a better message: この説明文を使うと,前述のアサーションは,より分かりやすいメッセージを出力します: :: Value of: some_expression Expected: is divisible by 7 Actual: 27 (the remainder is 6) .. You should let MatchAndExplain() print any additional information that can help a user understand the match result. Note that it should explain why the match succeeds in case of a success (unless it's obvious) - this is useful when the matcher is used inside Not(). There is no need to print the argument value itself, as Google Mock already prints it for you. MatchAndExplain() において任意の追加情報を出力し,ユーザがマッチ結果を理解しやすいようにするべきです.成功の場合は,(明らかな場合は除いて)なぜマッチが成功したのかを説明するべきであることに注意してください.- これは, matcher が Not() 内部で利用される場合に役立ちます.Google Mock は既に引数の値を出力するので,それを改めて出力する必要はありません. .. Notes: **注意事項:** .. The type of the value being matched (arg_type) is determined by the context in which you use the matcher and is supplied to you by the compiler, so you don't need to worry about declaring it (nor can you). This allows the matcher to be polymorphic. For example, IsDivisibleBy7() can be used to match any type where the value of (arg % 7) == 0 can be implicitly converted to a bool. In the Bar(IsDivisibleBy7()) example above, if method Bar() takes an int, arg_type will be int; if it takes an unsigned long, arg_type will be unsigned long; and so on. .. Google Mock doesn't guarantee when or how many times a matcher will be invoked. Therefore the matcher logic must be purely functional (i.e. it cannot have any side effect, and the result must not depend on anything other than the value being matched and the matcher parameters). This requirement must be satisfied no matter how you define the matcher (e.g. using one of the methods described in the following recipes). In particular, a matcher can never call a mock function, as that will affect the state of the mock object and Google Mock. #. マッチされる値の型(arg_type)は,matcher を利用する際のコンテキストにより決まるもので,これはコンパイラによって提供されます.よって,これの宣言について心配する必要はありません(し,そもそも宣言できません).これによって,matcher が多様性を持ちます.例えば,IsDivisibleBy(7) は,(arg % 7) == 0 の値が暗黙のうちに bool に変換可能な任意の型に対して利用できます.上述の Bar(IsDivisibleBy7()) の例では,メソッド Bar() が int を引数にとると arg_type は int に,unsigned long をとると arg_type も unsigned long になります. #. Google Mock は,matcher がいつ,何回呼び出されるかを保証しません.したがって,matcher のロジックは純粋関数的(つまり,副作用がなく,その結果は,マッチしている値と matcher のパラメータ以外には影響を受けないもの)でなければいけません.これは,どのように matcher を定義するか(例えば,以降のレシピで説明されるような方法を利用する,など)に関係なく,必ず満足されるべきです.特に,モックオブジェクトと Google Mock の状態に影響を与えてしまうので,matcher はモック関数を呼ぶことができません. .. Writing New Parameterized Matchers Quickly .. _cookbook_writing_new_parameterized_matchers_quickly: パラメータ化された新規の matcher を簡単に書く -------------------------------------------------------------- .. Sometimes you'll want to define a matcher that has parameters. For that you can use the macro: パラメータを持つ matcherを定義したいことがあります.そのためには,次のマクロを利用します: .. code-block:: c MATCHER_P(name, param_name, description_string) { statements; } .. where the description string can be either "" or a string expression that references negation and param_name. ここで,説明文字列には "" や,negation および param_name を参照する文字列式が利用できます. .. For example: 以下に例を示します: .. code-block:: c MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } .. will allow you to write: この定義により,次のように書くことができます: .. code-block:: c EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); .. which may lead to this message (assuming n is 10): (n が 10 だとすると)これは次のようなメッセージを出力します: :: Value of: Blah("a") Expected: has absolute value 10 Actual: -9 .. Note that both the matcher description and its parameter are printed, making the message human-friendly. ヒューマンフレンドリーなメッセージになるように,matcher の説明文とパラメータの両方が出力されることに注意してください .. In the matcher definition body, you can write foo_type to reference the type of a parameter named foo. For example, in the body of MATCHER_P(HasAbsoluteValue, value) above, you can write value_type to refer to the type of value. matcher 定義本体では,foo という名前のパラメータの型を参照するために foo_type を使うことができます.例えば,前述の MATCHER_P(HasAbsoluteValue, value) の定義では,value の型を参照するための value_type を利用できます. .. Google Mock also provides MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to support multi-parameter matchers: Google Mock では,MATCHER_P2, MATCHER_P3, から MATCHER_P10 までの,複数パラメタ用 matcher が用意されています: .. code-block:: c MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } .. Please note that the custom description string is for a particular instance of the matcher, where the parameters have been bound to actual values. Therefore usually you'll want the parameter values to be part of the description. Google Mock lets you do that by referencing the matcher parameters in the description string expression. カスタムされた説明文字列は,matcher の特定の **インスタンス** に対してのものであることに注意してください.そこでは,パラメータが実際のある値である事を前提としています.したがって,パラメータ値を説明文の一部として出力してほしいと思うのが普通です.Google Mock では,説明文字列式の中で matcher のパラメータを参照することで,それを可能にします. .. For example, 以下に例を示します: .. code-block:: c using ::testing::PrintToString; MATCHER_P2(InClosedRange, low, hi, std::string(negation ? "isn't" : "is") + " in range [" + PrintToString(low) + ", " + PrintToString(hi) + "]") { return low <= arg && arg <= hi; } ... EXPECT_THAT(3, InClosedRange(4, 6)); .. would generate a failure that contains the message: これは,次のようなメッセージを含む失敗を生成します: .. code-block:: c Expected: is in range [4, 6] .. If you specify "" as the description, the failure message will contain the sequence of words in the matcher name followed by the parameter values printed as a tuple. For example, 説明文として "" を指定した場合,matcher 名を構成する一連の文字の後に,タプルとして出力されるパラメータ値が続く失敗メッセージになります.以下に例を示します: .. code-block:: c MATCHER_P2(InClosedRange, low, hi, "") { ... } ... EXPECT_THAT(3, InClosedRange(4, 6)); .. would generate a failure that contains the text: これは,以下のテキストを含む失敗を生成します: :: Expected: in closed range (4, 6) .. For the purpose of typing, you can view タイプする量を減らすために,次のような表現も可能です. .. code-block:: c MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } .. as shorthand for これは,以下の省略表現です. .. code-block:: c template FooMatcherPk Foo(p1_type p1, ..., pk_type pk) { ... } .. When you write Foo(v1, ..., vk), the compiler infers the types of the parameters v1, ..., and vk for you. If you are not happy with the result of the type inference, you can specify the types by explicitly instantiating the template, as in Foo(5, false). As said earlier, you don't get to (or need to) specify arg_type as that's determined by the context in which the matcher is used. Foo(v1, ..., vk) と書くと,コンパイラがパラメータ v1, ..., vk の型を推定します.推定された型がふさわしくないものならば,Foo(5, false) というように,テンプレートを明示的にインスタンス化することで型を指定することができます.以前述べたように,arg_type は matcher が利用されるコンテキストによって決められるので,この指定は行いません(必要がありません). .. You can assign the result of expression to a variable of type FooMatcherPk. This can be useful when composing matchers. Matchers that don't have a parameter or have only one parameter have special types: you can assign Foo() to a FooMatcher-typed variable, and assign Foo(p) to a FooMatcherP-typed variable. また, FooMatcherPk 型の変数に,式 Foo(p1, ..., pk) の結果を代入することができます.これは,matcher を組み合わせる際に便利です.パラメータを持たない matcher ,または1つのパラメータだけを持つ matcher は,特別な型を持ちます:Foo() は FooMatcher 型の変数に代入でき,Foo(p) は FooMatcherP 型の変数に代入できます. .. While you can instantiate a matcher template with reference types, passing the parameters by pointer usually makes your code more readable. If, however, you still want to pass a parameter by reference, be aware that in the failure message generated by the matcher you will see the value of the referenced object but not its address. 参照する型に応じて matcher テンプレートをインスタンス化できますが,そのパラメータをポインタで渡すと,コードが読みやすくなることが多いです.しかし,もしパラメータを参照で渡したいならば,matcher に生成される失敗メッセージ中に表示されるのは,参照されたオブジェクトのアドレスではなく値である,という点に注意してください. .. You can overload matchers with different numbers of parameters: 異なる数のパラメータをとる matcher をオーバーロードすることができます: .. code-block:: c MATCHER_P(Blah, a, description_string_1) { ... } MATCHER_P2(Blah, a, b, description_string_2) { ... } .. While it's tempting to always use the MATCHER* macros when defining a new matcher, you should also consider implementing MatcherInterface or using MakePolymorphicMatcher() instead (see the recipes that follow), especially if you need to use the matcher a lot. While these approaches require more work, they give you more control on the types of the value being matched and the matcher parameters, which in general leads to better compiler error messages that pay off in the long run. They also allow overloading matchers based on parameter types (as opposed to just based on the number of parameters). 新しい matcher を定義する際に,常に MATCHER* マクロを利用するという選択肢は魅力的ですが,それの代わりに,MatcherInterface を実装したり, MakePolymorphicMatcher() (後述のレシピを参照)を利用したりすることを考慮するべきです.大量の matcher を利用する必要がある場合は,特にそうです.これらのアプローチでは,やることは多いですが,マッチされている値の型や matcher のパラメータの制御を行うことができます.通常は,それによって,コンパイルエラーメッセージがより分かりやすいものになるので,長い目で見れば優れいていると言えます.また,(単にパラメータの個数に基づくものではなく)パラメータの型に基づいた matcher のオーバーロードも可能になります. .. Writing New Monomorphic Matchers .. _cookbook_writing_new_monomorphic_matchers: 新規の モノモーフィック matcher を書く ----------------------------------------------------- .. A matcher of argument type T implements ::testing::MatcherInterface and does two things: it tests whether a value of type T matches the matcher, and can describe what kind of values it matches. The latter ability is used for generating readable error messages when expectations are violated. 引数の型が T である matcher は, ::testing::MatcherInterface を実装し,2つのことを実行します:型が T である値が matcher にマッチするかどうかをテストします.そして,マッチする値がどういう種類のものなのかを記述します.後者の機能は,Expectation が満たされなかった場合に,読みやすいエラーメッセージを生成するために利用されます. .. The interface looks like this: そのインタフェースは,次のようになります: .. code-block:: c class MatchResultListener { public: ... // 内部の ostream に x を流し込みます.もし, ostream が // NULL の場合には何もしません. template MatchResultListener& operator<<(const T& x); // 内部の ostream を返します. ::std::ostream* stream(); }; template class MatcherInterface { public: virtual ~MatcherInterface(); // matcher が x にマッチした場合にのみ true を返します. // また,そのマッチ結果を `listener` に説明します. virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; // この matcher の説明を ostream に書きだします. virtual void DescribeTo(::std::ostream* os) const = 0; // この matcher の negation の説明を ostream に書きだします. virtual void DescribeNegationTo(::std::ostream* os) const; }; .. If you need a custom matcher but Truly() is not a good option (for example, you may not be happy with the way Truly(predicate) describes itself, or you may want your matcher to be polymorphic as Eq(value) is), you can define a matcher to do whatever you want in two steps: first implement the matcher interface, and then define a factory function to create a matcher instance. The second step is not strictly needed but it makes the syntax of using the matcher nicer. カスタム matcher が必要にもかかわらず,Truly() を使う選択肢が適切でない場合(例えば,Truly(predicate) を使った場合の自分自身の説明が適切でない場合,または Eq(value) のようにポリモーフィックな matcher が欲しい場合,などです),完全に自分の望む動作をする matcher を2段階で定義します:まず,matcher インタフェースを実装して,それから,matcher インスタンスを作成するファクトリ関数を定義します.これの,第2段階部分は必須というわけではないですが,matcher の構文を便利なものにしてくれます. .. For example, you can define a matcher to test whether an int is divisible by 7 and then use it like this: 例えば次のようにすると,ある整数が 7 で割り切れるかどうかをテストする matcher を定義して,それを利用できます: .. code-block:: c using ::testing::MakeMatcher; using ::testing::Matcher; using ::testing::MatcherInterface; using ::testing::MatchResultListener; class DivisibleBy7Matcher : public MatcherInterface { public: virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { return (n % 7) == 0; } virtual void DescribeTo(::std::ostream* os) const { *os << "is divisible by 7"; } virtual void DescribeNegationTo(::std::ostream* os) const { *os << "is not divisible by 7"; } }; inline Matcher DivisibleBy7() { return MakeMatcher(new DivisibleBy7Matcher); } ... EXPECT_CALL(foo, Bar(DivisibleBy7())); .. You may improve the matcher message by streaming additional information to the listener argument in MatchAndExplain(): MatchAndExplain() の listener 引数に対して,追加の情報を流し込むことで,この matcher メッセージを改良することができます. .. code-block:: c class DivisibleBy7Matcher : public MatcherInterface { public: virtual bool MatchAndExplain(int n, MatchResultListener* listener) const { const int remainder = n % 7; if (remainder != 0) { *listener << "the remainder is " << remainder; } return remainder == 0; } ... }; .. Then, EXPECT_THAT(x, DivisibleBy7()); may general a message like this: EXPECT_THAT(x, DivisibleBy7()); は,次のようなメッセージを生成します: :: Value of: x Expected: is divisible by 7 Actual: 23 (the remainder is 2) .. Writing New Polymorphic Matchers .. _cookbook_writing_new_polymorphic_matchers: 新規の ポリモーフィック matcher を書く ------------------------------------------------- .. You've learned how to write your own matchers in the previous recipe. Just one problem: a matcher created using MakeMatcher() only works for one particular type of arguments. If you want a polymorphic matcher that works with arguments of several types (for instance, Eq(x) can be used to match a value as long as value == x compiles -- value and x don't have to share the same type), you can learn the trick from "gmock/gmock-matchers.h" but it's a bit involved. 上述のレシピでは,独自の matcher を書く方法を学びました.ただし,1つだけ問題があります:MakeMatcher() を使って作成された matcher は,引数の特定の型に対してのみ動作するということです.もし,複数の型に対して動作するポリモーフィックな matcher (例えば Eq(x) の場合, value == x がコンパイル可能ならば,value に対するマッチに利用できます.ここで, value と x は同じ型である必要はありません)が必要ならば, "gmock/gmock-matchers.h" に書かれてあるトリックを学ぶのもありです.ただし,少しややこしいですが. .. Fortunately, most of the time you can define a polymorphic matcher easily with the help of MakePolymorphicMatcher(). Here's how you can define NotNull() as an example: 幸いなことに,MakePolymorphicMatcher() を利用すれば,大抵の場合,簡単にポリモーフィック matcher を定義することができます.ここでは例として,NotNull() を定義する方法を示します: .. code-block:: c using ::testing::MakePolymorphicMatcher; using ::testing::MatchResultListener; using ::testing::NotNull; using ::testing::PolymorphicMatcher; class NotNullMatcher { public: // ポリモーフィック matcher を実装するために,まず, // 以下のように MatchAndExplain(), DescribeTo(), DescribeNegationTo() // の3つのメンバ関数を持つ「コピー可能な」クラスを定義します. // この例では,NotNull() を任意のポインタに対して利用したいので, // MatchAndExplain() は,第1引数として任意の型のポインタを受け取ります. // 通常,MatchAndExplain() を,普通のメソッドやメソッドテンプレート // のように定義するか,または,それをオーバーロードします. template bool MatchAndExplain(T* p, MatchResultListener* /* listener */) const { return p != NULL; } // この matcher にマッチする値の性質を記述します. void DescribeTo(::std::ostream* os) const { *os << "is not NULL"; } // この matcher にマッチしない値の性質を記述します. void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } }; // ポリモーフィック matcher を作成するには,そのクラスのインスタンスを // MakePolymorphicMatcher() に渡します.戻り値の型に注意してください. inline PolymorphicMatcher NotNull() { return MakePolymorphicMatcher(NotNullMatcher()); } ... EXPECT_CALL(foo, Bar(NotNull())); // この引数は,必ず NULL ではないポインタです. .. Note: Your polymorphic matcher class does not need to inherit from MatcherInterface or any other class, and its methods do not need to be virtual. **注意:** ポリモーフィック matcher クラスは,MatcherInterface などの他のクラスを継承する必要は **ありません.** そして,そのメソッドも virtual である必要は **ありません.** .. Like in a monomorphic matcher, you may explain the match result by streaming additional information to the listener argument in MatchAndExplain(). モノモーフィック matcher のように,MatchAndExplain() の listener 引数に追加情報を流し込んで,マッチ結果を説明することもできます. .. Writing New Cardinalities .. _cookbook_writing_new_cardinalities: 新規の Cardinality を書く ----------------------------------- .. A cardinality is used in Times() to tell Google Mock how many times you expect a call to occur. It doesn't have to be exact. For example, you can say AtLeast(5) or Between(2, 4). cardinality は,ある呼び出しに期待する発生回数を Google Mock に伝えるために,Times() で利用されます.これは厳密な回数である必要はありません.例えば,AtLeast(5) や Between(2, 4) という書き方もできます. .. If the built-in set of cardinalities doesn't suit you, you are free to define your own by implementing the following interface (in namespace testing): cardinality の組み込みセットでは不十分ならば,(testing 名前空間にある)次に示すインタフェースを実装することで,自由にそれを定義することができます: .. code-block:: c class CardinalityInterface { public: virtual ~CardinalityInterface(); // call_count の呼び出しが,この cardinality を満足する場合にのみ true を返します. virtual bool IsSatisfiedByCallCount(int call_count) const = 0; // call_count の呼び出しが,この cardinality を飽和する場合にのみ true を返します. virtual bool IsSaturatedByCallCount(int call_count) const = 0; // 自分自身の説明を ostream に出力します. virtual void DescribeTo(::std::ostream* os) const = 0; }; .. For example, to specify that a call must occur even number of times, you can write 例えば,呼び出しが必ず偶数回でなければいけないならば,次のように書きます. .. code-block:: c using ::testing::Cardinality; using ::testing::CardinalityInterface; using ::testing::MakeCardinality; class EvenNumberCardinality : public CardinalityInterface { public: virtual bool IsSatisfiedByCallCount(int call_count) const { return (call_count % 2) == 0; } virtual bool IsSaturatedByCallCount(int call_count) const { return false; } virtual void DescribeTo(::std::ostream* os) const { *os << "called even number of times"; } }; Cardinality EvenNumber() { return MakeCardinality(new EvenNumberCardinality); } ... EXPECT_CALL(foo, Bar(3)) .Times(EvenNumber()); .. Writing New Actions Quickly .. _cookbook_writing_new_actions_quickly: 新規の Action を簡単に書く ----------------------------------- .. If the built-in actions don't work for you, and you find it inconvenient to use Invoke(), you can use a macro from the ACTION* family to quickly define a new action that can be used in your code as if it's a built-in action. もし,組み込みの Action では不十分で,Invoke() を使うのが不便だと思うならば,新しい Action を素早く定義するのに ACTION* 形式のマクロを利用できます.この Action は,あなたのコード内で,組み込みの Action と同様に利用できます. .. By writing 次のように書きます. .. code-block:: c ACTION(name) { statements; } .. in a namespace scope (i.e. not inside a class or function), you will define an action with the given name that executes the statements. The value returned by statements will be used as the return value of the action. Inside the statements, you can refer to the K-th (0-based) argument of the mock function as argK. For example: これによって,名前空間内部で(つまり,クラスや関数の内部ではありません),statements を実行する name という名前の Action が定義されます.statements に返される値が,この Action の戻り値として利用されます.statements 内部では,モック関数の K-番目(0基準)の引数を argK として参照できます.次に例を示します: .. code-block:: c ACTION(IncrementArg1) { return ++(*arg1); } .. allows you to write これにより,次のように書くことができます. .. code-block:: c ... WillOnce(IncrementArg1()); .. Note that you don't need to specify the types of the mock function arguments. Rest assured that your code is type-safe though: you'll get a compiler error if *arg1 doesn't support the ++ operator, or if the type of ++(*arg1) isn't compatible with the mock function's return type. ここで,モック関数の引数の型を指定する必要がないことに注意してください.しかし,あなたのコードは型安全なので安心してください:*arg1 が ++ 演算子をサポートしていない場合,または,++(*arg1) の型がモック関数の戻り値と互換性がない場合は,コンパイルエラーが起こります. .. Another example: さらに,別の例を示します: .. code-block:: c ACTION(Foo) { (*arg2)(5); Blah(); *arg1 = 0; return arg0; } .. defines an action Foo() that invokes argument #2 (a function pointer) with 5, calls function Blah(), sets the value pointed to by argument #1 to 0, and returns argument #0. これは,以下のような動作を行う Action Foo() を定義します.まず,2番目の引数(関数ポインタ)に 5 を与えて実行します.そして,関数 Blah() を呼び出します.さらに,1番目の引数によって指される値に 0 をセットします.最後に,0番目の引数を返します. .. For more convenience and flexibility, you can also use the following pre-defined symbols in the body of ACTION: 利便性と柔軟性のために,ACTION の定義部分で,次のような定義済みシンボルを利用することもできます: .. "argK_type", "The type of the K-th (0-based) argument of the mock function" .. "args", "All arguments of the mock function as a tuple" .. "args_type", "The type of all arguments of the mock function as a tuple" .. "return_type", "The return type of the mock function" .. "function_type", "The type of the mock function" .. csv-table:: :header: :widths: 10, 40 "argK_type", "モック関数のK-番目(0基準)の引数の型" "args", "タプルで表現された,モック関数の全ての引数" "args_type", "タプルで表現された,モック関数の全ての引数の型" "return_type", "モック関数の戻り値の型" "function_type", "モック関数の型" .. For example, when using an ACTION as a stub action for mock function: 例えば,次のようなモック関数のスタブ Action として ACTION を利用する場合を考えます: .. code-block:: c int DoSomething(bool flag, int* ptr); .. we have: ここで,以下のシンボルを利用できます: .. :header: Pre-defined Symbol, Is Bound To .. "arg0", "the value of flag" .. "arg0_type", "the type bool" .. "arg1", "the value of ptr" .. "arg1_type", "the type int*" .. "args", "the tuple (flag, ptr)" .. "args_type", "the type std::tr1::tuple" .. "return_type", "the type int" .. "function_type", "the type int(bool, int*)" .. csv-table:: :header: 定義済みシンボル, 紐づけられた先 :widths: 10, 20 "arg0", "flag の値" "arg0_type", "bool 型" "arg1", "ptr の値" "arg1_type", "int* 型" "args", "タプル (flag, ptr)" "args_type", "std::tr1::tuple 型" "return_type", "int 型" "function_type", "int(bool, int*) 型" .. Writing New Parameterized Actions Quickly .. _cookbook_writing_new_parameterized_actions_quickly: 新規の パラメータ化された Action を簡単に書く ----------------------------------------------------- .. Sometimes you'll want to parameterize an action you define. For that we have another macro あなたが定義した Action をパラメータ化したい場合もあるでしょう.それ用のマクロを用意してあります. .. code-block:: c ACTION_P(name, param) { statements; } .. For example, 例えば,次のように書きます. .. code-block:: c ACTION_P(Add, n) { return arg0 + n; } .. will allow you to write これにより,以下のように書くことができます. .. code-block:: c // 0番目の引数 + 5 を返します. ... WillOnce(Add(5)); .. For convenience, we use the term arguments for the values used to invoke the mock function, and the term parameters for the values used to instantiate an action. ここでは便宜上,モック関数の実行時に使われる値を表すのに *引数* ,Action をインスタンス化するための値を表すのに *パラメータ* という表現を用います. .. Note that you don't need to provide the type of the parameter either. Suppose the parameter is named param, you can also use the Google-Mock-defined symbol param_type to refer to the type of the parameter as inferred by the compiler. For example, in the body of ACTION_P(Add, n) above, you can write n_type for the type of n. パラメータの型を与える必要もないことに注意してください.パラメータが param という名前だとすると,Google-Mock が定義した シンボル param_type を利用して,コンパイラによって推定されたパラメータの型を参照することができます.例えば,上述した ACTION_P(Add, n) の定義部分で,n の型を参照するのに n_type を利用することができます. .. Google Mock also provides ACTION_P2, ACTION_P3, and etc to support multi-parameter actions. For example, Google Mock には,ACTION_P2,ACTION_P3 などの,マルチパラメータ Action をサポートするものも用意されています.例えば, .. code-block:: c ACTION_P2(ReturnDistanceTo, x, y) { double dx = arg0 - x; double dy = arg1 - y; return sqrt(dx*dx + dy*dy); } .. lets you write とすると,次のように書くことができます. .. code-block:: c ... WillOnce(ReturnDistanceTo(5.0, 26.5)); .. You can view ACTION as a degenerated parameterized action where the number of parameters is 0. ACTION は,パラメータ化された Action の劣化版,つまりパラメータ数が 0 個のもの,と見なすこともできます. .. You can also easily define actions overloaded on the number of parameters: また,パラメータ数をオーバーロードした Action も簡単に定義できます: .. code-block:: c ACTION_P(Plus, a) { ... } ACTION_P2(Plus, a, b) { ... } .. Restricting the Type of an Argument or Parameter in an ACTION .. _cookbook_restricting_the_type_of_an_argument_or_parameter_in_an_ACTION: ACTION の引数やパラメータの型を制限する -------------------------------------------------------------------------- .. For maximum brevity and reusability, the ACTION* macros don't ask you to provide the types of the mock function arguments and the action parameters. Instead, we let the compiler infer the types for us. 最も簡潔かつ再利用可能にするため,ACTION* マクロでは,モック関数の引数の型と Action パラメータの型を与えなくても構いません.代わりに,それらの型をコンパイラに推定してもらいます. .. Sometimes, however, we may want to be more explicit about the types. There are several tricks to do that. For example: しかし,場合によっては,その型について明示したいことがあるでしょう.それを行うためのトリックがいくつかあります.例を示しましょう: .. code-block:: c ACTION(Foo) { // arg0 が確実に int に変換できることを確認します. int n = arg0; // ... ここでは,arg0 の代わりに n を利用します ... } ACTION_P(Bar, param) { // arg1 の型が const char* であることを確認します. ::testing::StaticAssertTypeEq(); // param が確実に bool に変換できることを確認します. bool flag = param; } .. where StaticAssertTypeEq is a compile-time assertion in Google Test that verifies two types are the same. ここで, StaticAssertTypeEq は,2つの型が同じであることを検証する,Google Test のコンパイル時アサーションです. .. Writing New Action Templates Quickly .. _cookbook_writing_new_action_templates_quickly: 新規の Action テンプレートを簡単に書く ---------------------------------------------- .. Sometimes you want to give an action explicit template parameters that cannot be inferred from its value parameters. ACTION_TEMPLATE() supports that and can be viewed as an extension to ACTION() and ACTION_P*(). 場合によっては,値パラメータからの推定が不可能なテンプレートパラメータを明示的に Action に渡したいこともあるでしょう.ACTION_TEMPLATE() は,それをサポートするもので,ACTION() と ACTION_P*() の拡張のように見なすことができます. .. The syntax: 構文は次のようになります: .. code-block:: c ACTION_TEMPLATE(ActionName, HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } .. defines an action template that takes m explicit template parameters and n value parameters, where m is between 1 and 10, and n is between 0 and 10. name_i is the name of the i-th template parameter, and kind_i specifies whether it's a typename, an integral constant, or a template. p_i is the name of the i-th value parameter. これは,m 個の明示的なテンプレートパラメータ,および n 個の値パラメータを受け取る Action テンプレートを定義します.ここで,m は 1 から 10 の間,n は 0 から 10 の間の数です.name_i は,i-番目のテンプレートパラメータの名前であり,kind_i は,それが typename ,整数の値,テンプレートのいずれであるかを示します.また,p_i は,i-番目の値パラメータの名前です. .. Example: 例: .. code-block:: c // DuplicateArg(output) は,モック関数の k-番目の引数を // 型 T に変換して,それを *output にコピーします. ACTION_TEMPLATE(DuplicateArg, // Note the comma between int and k: HAS_2_TEMPLATE_PARAMS(int, k, typename, T), AND_1_VALUE_PARAMS(output)) { *output = T(std::tr1::get(args)); } .. To create an instance of an action template, write: Action テンプレートのインスタンスを作成するには,次のように書きます: .. code-block:: c ActionName(v1, ..., v_n) .. where the ts are the template arguments and the vs are the value arguments. The value argument types are inferred by the compiler. For example: ここで t はテンプレート引数で,v は値引数です.値引数の型は,コンパイラによって推定されます.例えば,次のようになります: .. code-block:: c using ::testing::_; ... int n; EXPECT_CALL(mock, Foo(_, _)) .WillOnce(DuplicateArg<1, unsigned char>(&n)); .. If you want to explicitly specify the value argument types, you can provide additional template arguments: 値引数の型を明示的に指定したい場合,追加テンプレート引数に追加して渡すことができます: .. code-bock:: c ActionName(v1, ..., v_n) .. where u_i is the desired type of v_i. ここで, u_i は,希望する v_i の型となります. .. ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the number of value parameters, but not on the number of template parameters. Without the restriction, the meaning of the following is unclear: ACTION_TEMPLATE および ACTION/ACTION_P* は,値パラメータの数を変えてオーバーロードすることができますが,テンプレートパラメータの数に対しては,そういうことはできません.もし,この制限がなければ,以下のような場合の解釈があいまいになります: .. code-block:: c OverloadedAction(x); .. Are we using a single-template-parameter action where bool refers to the type of x, or a two-template-parameter action where the compiler is asked to infer the type of x? これは,1つのテンプレートパラメータを持つ Action で,bool は x の型を参照するものなのでしょうか,それとも,2つのテンプレートパラメータを持つ Action で,x の型はコンパイラが推定するのでしょうか? .. Using the ACTION Object's Type .. _cookbook_using_the_ACTION_objects_type: ACTION オブジェクトの型を利用する -------------------------------------------- .. If you are writing a function that returns an ACTION object, you'll need to know its type. The type depends on the macro used to define the action and the parameter types. The rule is relatively simple: ACTION オブジェクトを返す関数を書く場合,その型を知っておく必要があります.その型は,Action を定義するマクロとそのパラメータ型に依存します.そのルールは,比較的シンプルです: .. :header: Given Definition, Expression, Has Type .. csv-table:: :header: 定義, 式, 型 :widths: 30, 15, 15 "ACTION(Foo)", "Foo()", "FooAction" "ACTION_TEMPLATE(Foo, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())", "Foo()", "FooAction" "ACTION_P(Bar, param)", "Bar(int_value)", "BarActionP" "ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))", "Bar(int_value)", "FooActionP" "ACTION_P2(Baz, p1, p2)", "Baz(bool_value, int_value)", "BazActionP2" "ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))", "Baz(bool_value, int_value)", "FooActionP2" "...", "...", "..." .. Note that we have to pick different suffixes (Action, ActionP, ActionP2, and etc) for actions with different numbers of value parameters, or the action definitions cannot be overloaded on the number of them. 値パラメータの個数が異なる Action に対しては,異なるサフィックスを付ける必要がある(Action,ActionP,ActionP2 など)ことに注意してください.そうしなければ,Action の定義がオーバーロードされてしまいます. .. Writing New Monomorphic Actions .. _cookbook_writing_new_monomorphic_actions: 新規の モノモーフィック Action を書く ------------------------------------------------ .. While the ACTION* macros are very convenient, sometimes they are inappropriate. For example, despite the tricks shown in the previous recipes, they don't let you directly specify the types of the mock function arguments and the action parameters, which in general leads to unoptimized compiler error messages that can baffle unfamiliar users. They also don't allow overloading actions based on parameter types without jumping through some hoops. ACTION* マクロは非常に便利ですが,時には適切ではない場合もあります.例えば,前述のレシピで説明したトリックを用いても,モック関数の引数の型,およびアクションパラメータの型を,直接指定することはできず,そのようなことをすると,慣れていないユーザを困惑させるコンパイラのエラーメッセージが出されるのが普通です.また,いくつかの要求に従う事なしには,パラメータの型のオーバーロードもできません. .. An alternative to the ACTION* macros is to implement ::testing::ActionInterface, where F is the type of the mock function in which the action will be used. For example: ACTION* マクロに変わる代替手段は, ::testing::ActionInterface を実装することです.ここで F は,その中で Action が利用されるモック関数の型です. .. code-block:: c template class ActionInterface { public: virtual ~ActionInterface(); // Action を実行します.結果は,型 F の関数の戻り値型であり, // ArgumentTuple は,F の引数のタプルです. // // 例えば,F が int(bool, const string&) とすると,この結果は int になり, // ArgumentTuple は,tr1::tuple となります. virtual Result Perform(const ArgumentTuple& args) = 0; }; using ::testing::_; using ::testing::Action; using ::testing::ActionInterface; using ::testing::MakeAction; typedef int IncrementMethod(int*); class IncrementArgumentAction : public ActionInterface { public: virtual int Perform(const tr1::tuple& args) { int* p = tr1::get<0>(args); // 最初の引数を捕まえます. return *p++; } }; Action IncrementArgument() { return MakeAction(new IncrementArgumentAction); } ... EXPECT_CALL(foo, Baz(_)) .WillOnce(IncrementArgument()); int n = 5; foo.Baz(&n); // 5が返され,nは6に変更されます. .. Writing New Polymorphic Actions .. _cookbook_writing_new_polymorphic_actions: 新規の ポリモーフィック Action を書く --------------------------------------------- .. The previous recipe showed you how to define your own action. This is all good, except that you need to know the type of the function in which the action will be used. Sometimes that can be a problem. For example, if you want to use the action in functions with different types (e.g. like Return() and SetArgPointee()). 前述のレシピでは,独自の Action を定義する方法を説明しました.関数(この中で Action が利用されます)の型を知る必要があることを除けば,これは良いことずくめの方法です.しかし,これが問題になる場合もあります.例えば,(Return() と SetArgPointee() のように)複数の異なる型の関数内で Action を利用したい場合です. .. If an action can be used in several types of mock functions, we say it's polymorphic. The MakePolymorphicAction() function template makes it easy to define such an action: 複数の型のモック関数内で利用できる Action を, *ポリモーフィック* であるといいます. MakePolymorphicAction() 関数テンプレートを使うと,このような Action を簡単に定義できます: .. code-block:: c namespace testing { template PolymorphicAction MakePolymorphicAction(const Impl& impl); } // testing 名前空間 .. As an example, let's define an action that returns the second argument in the mock function's argument list. The first step is to define an implementation class: 例として,モック関数の引数リストの内,2番目の引数を返すような Action を定義してみましょう.最初のステップは,実装クラスを定義することです: .. code-block:: c class ReturnSecondArgumentAction { public: template Result Perform(const ArgumentTuple& args) const { // i-番目(0基準)の引数を得るには, tr1::get(args) を使います. return tr1::get<1>(args); } }; .. This implementation class does not need to inherit from any particular class. What matters is that it must have a Perform() method template. This method template takes the mock function's arguments as a tuple in a single argument, and returns the result of the action. It can be either const or not, but must be invokable with exactly one template argument, which is the result type. In other words, you must be able to call Perform(args) where R is the mock function's return type and args is its arguments in a tuple. この実装クラスは,基底クラスを継承する必要がありません.必ず Perform() メソッドテンプレートを持つ,という事が肝心なのです.このメソッドテンプレートは,モック関数の引数を要素とする **1つの** タプル,を引数にとり,この Action の結果を返します.const でも,そうでなくても構いませんが,厳密に1つのテンプレート引数,つまり結果の型を与えて実行可能なものである必要があります.言い換えれば,必ず Perform(args) を呼び出すことができなければいけない,とうことです.ここで,R はモック関数の戻り値型であり,args はその引数を要素とするタプルです. .. Next, we use MakePolymorphicAction() to turn an instance of the implementation class into the polymorphic action we need. It will be convenient to have a wrapper for this: 次のステップでは,MakePolymorphicAction() を使って,この実装クラスのインスタンスを必要なポリモーフィック Action に変換します.これ用のラッパーがあれば便利でしょう: .. code-block:: c using ::testing::MakePolymorphicAction; using ::testing::PolymorphicAction; PolymorphicAction ReturnSecondArgument() { return MakePolymorphicAction(ReturnSecondArgumentAction()); } .. Now, you can use this polymorphic action the same way you use the built-in ones: これで,組み込みのものと同様に,ポリモーフィック Action を使うことができます: .. code-block:: c using ::testing::_; class MockFoo : public Foo { public: MOCK_METHOD2(DoThis, int(bool flag, int n)); MOCK_METHOD3(DoThat, string(int x, const char* str1, const char* str2)); }; ... MockFoo foo; EXPECT_CALL(foo, DoThis(_, _)) .WillOnce(ReturnSecondArgument()); EXPECT_CALL(foo, DoThat(_, _, _)) .WillOnce(ReturnSecondArgument()); ... foo.DoThis(true, 5); // 5 を返します. foo.DoThat(1, "Hi", "Bye"); // "Hi" を返します. .. Teaching Google Mock How to Print Your Values .. _cookbook_teaching_gmock_how_to_print_your_values: Google Mock に値の表示方法を教示する -------------------------------------------- .. When an uninteresting or unexpected call occurs, Google Mock prints the argument values and the stack trace to help you debug. Assertion macros like EXPECT_THAT and EXPECT_EQ also print the values in question when the assertion fails. Google Mock and Google Test do this using Google Test's user-extensible value printer. 不要な,または期待されない呼び出しが起こった場合,Google Mock は,デバッグの助けになるように,その引数の値とスタックトレースを出力します.EXPECT_THAT や EXPECT_EQ のようなアサーションマクロも,そのアサーションが失敗した時には,式の値を出力します.Google Mock と Google Test は,ユーザが拡張可能な値プリンタという Google Test の機能を利用して,これを行います. .. This printer knows how to print built-in C++ types, native arrays, STL containers, and any type that supports the << operator. For other types, it prints the raw bytes in the value and hopes that you the user can figure it out. Google Test's advanced guide explains how to extend the printer to do a better job at printing your particular type than to dump the bytes. このプリンタは,C++ の組み込み型,ネイティブな配列,STL コンテナ,<< 演算子をサポートする任意の型を出力することができます.しかし,その他の型の場合は,生のバイト値を表示して,ユーザがそれの意味を分かってくれることを願うのみです.特定の型を,バイトダンプするよりも綺麗な形式で出力できるようにこのプリンタを拡張する方法は,Google Test の `上級ガイド `_ で説明されています.