// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef TESTING_GMOCK_MUTANT_H_ #define TESTING_GMOCK_MUTANT_H_ // The intention of this file is to make possible using GMock actions in // all of its syntactic beauty. // // // Sample usage with gMock: // // struct Mock : public ObjectDelegate { // MOCK_METHOD2(string, OnRequest(int n, const string& request)); // MOCK_METHOD1(void, OnQuit(int exit_code)); // MOCK_METHOD2(void, LogMessage(int level, const string& message)); // // string HandleFlowers(const string& reply, int n, const string& request) { // string result = SStringPrintf("In request of %d %s ", n, request); // for (int i = 0; i < n; ++i) result.append(reply) // return result; // } // // void DoLogMessage(int level, const string& message) { // } // // void QuitMessageLoop(int seconds) { // base::MessageLoop* loop = base::MessageLoop::current(); // loop->PostDelayedTask(FROM_HERE, // base::MessageLoop::QuitWhenIdleClosure(), // 1000 * seconds); // } // }; // // Mock mock; // // Will invoke mock.HandleFlowers("orchids", n, request) // // "orchids" is a pre-bound argument, and and are call-time // // arguments - they are not known until the OnRequest mock is invoked. // EXPECT_CALL(mock, OnRequest(Ge(5), base::StartsWith("flower")) // .Times(1) // .WillOnce(Invoke(CreateFunctor( // &Mock::HandleFlowers, base::Unretained(&mock), string("orchids")))); // // // // No pre-bound arguments, two call-time arguments passed // // directly to DoLogMessage // EXPECT_CALL(mock, OnLogMessage(_, _)) // .Times(AnyNumber()) // .WillAlways(Invoke(CreateFunctor( // &Mock::DoLogMessage, base::Unretained(&mock)))); // // // // In this case we have a single pre-bound argument - 3. We ignore // // all of the arguments of OnQuit. // EXCEPT_CALL(mock, OnQuit(_)) // .Times(1) // .WillOnce(InvokeWithoutArgs(CreateFunctor( // &Mock::QuitMessageLoop, base::Unretained(&mock), 3))); // // MessageLoop loop; // loop.Run(); // // // // Here is another example of how we can set an action that invokes // // method of an object that is not yet created. // struct Mock : public ObjectDelegate { // MOCK_METHOD1(void, DemiurgeCreated(Demiurge*)); // MOCK_METHOD2(void, OnRequest(int count, const string&)); // // void StoreDemiurge(Demiurge* w) { // demiurge_ = w; // } // // Demiurge* demiurge; // } // // EXPECT_CALL(mock, DemiurgeCreated(_)).Times(1) // .WillOnce(Invoke(CreateFunctor( // &Mock::StoreDemiurge, base::Unretained(&mock)))); // // EXPECT_CALL(mock, OnRequest(_, StrEq("Moby Dick"))) // .Times(AnyNumber()) // .WillAlways(WithArgs<0>(Invoke(CreateFunctor( // &Demiurge::DecreaseMonsters, base::Unretained(&mock->demiurge_))))); // #include "base/bind.h" namespace testing { template class CallbackToFunctorHelper; template class CallbackToFunctorHelper { public: explicit CallbackToFunctorHelper(const base::Callback& cb) : cb_(cb) {} template R operator()(RunArgs&&... args) { return cb_.Run(std::forward(args)...); } private: base::Callback cb_; }; template CallbackToFunctorHelper CallbackToFunctor(const base::Callback& cb) { return CallbackToFunctorHelper(cb); } template CallbackToFunctorHelper CreateFunctor( Functor functor) { return CallbackToFunctor(functor); } template CallbackToFunctorHelper> CreateFunctor(Functor functor, const BoundArgs&... args) { return CallbackToFunctor(base::Bind(functor, args...)); } } // namespace testing #endif // TESTING_GMOCK_MUTANT_H_