| // Copyright (c) 2009 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. |
| |
| // This file provides some utility classes that help with testing APIs which use |
| // callbacks. |
| // |
| // -- InvokeRunnable -- |
| // The InvokeRunnable is an action that can be used a gMock mock object to |
| // invoke the Run() method on mock argument. Example: |
| // |
| // class MockFoo : public Foo { |
| // public: |
| // MOCK_METHOD0(DoSomething, void(Task* done_cb)); |
| // }; |
| // |
| // EXPECT_CALL(foo, DoSomething(_)).WillOnce(WithArg<0>(InvokeRunnable())); |
| // |
| // Then you pass "foo" to something that will eventually call DoSomething(). |
| // The mock action will ensure that passed in done_cb is invoked. |
| // |
| // |
| // -- TaskMocker -- |
| // The TaskMocker class lets you create mock callbacks. Callbacks are |
| // difficult to mock because ownership of the callback object is often passed |
| // to the funciton being invoked. TaskMocker solves this by providing a |
| // GetTask() function that creates a new, single-use task that delegates to |
| // the originating TaskMocker object. Expectations are placed on the |
| // originating TaskMocker object. Each callback retrieved by GetTask() is |
| // tracked to ensure that it is properly deleted. The TaskMocker expects to |
| // outlive all the callbacks retrieved by GetTask(). |
| // |
| // Example: |
| // |
| // TaskMocker done_cb; |
| // EXPECT_CALL(done_cb, Run()).Times(3); |
| // |
| // func1(done_cb.GetTask()); |
| // func2(done_cb.GetTask()); |
| // func3(done_cb.GetTask()); |
| // |
| // // All 3 callbacks from GetTask() should be deleted before done_cb goes out |
| // // of scope. |
| // |
| // This class is not threadsafe. |
| // |
| // TODO(ajwong): Is it even worth bothering with gmock here? |
| // TODO(ajwong): Move MockFilterCallback here and merge the implementation |
| // differences. |
| |
| #ifndef MEDIA_BASE_MOCK_TASK_H_ |
| #define MEDIA_BASE_MOCK_TASK_H_ |
| |
| #include "base/task.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| |
| namespace media { |
| |
| ACTION(InvokeRunnable) { |
| arg0->Run(); |
| delete arg0; |
| } |
| |
| class TaskMocker { |
| public: |
| TaskMocker() |
| : outstanding_tasks_(0) { |
| } |
| ~TaskMocker() { |
| CHECK(outstanding_tasks_ == 0) |
| << "If outstanding_tasks_ is not zero, tasks have been leaked."; |
| } |
| |
| Task* CreateTask() { |
| return new CountingTask(this); |
| } |
| |
| MOCK_METHOD0(Run, void()); |
| |
| private: |
| friend class CountingTask; |
| class CountingTask : public Task { |
| public: |
| CountingTask(TaskMocker* origin) |
| : origin_(origin) { |
| origin_->outstanding_tasks_++; |
| } |
| |
| virtual void Run() { |
| origin_->Run(); |
| } |
| |
| virtual ~CountingTask() { |
| origin_->outstanding_tasks_--; |
| } |
| |
| private: |
| TaskMocker* origin_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CountingTask); |
| }; |
| |
| int outstanding_tasks_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TaskMocker); |
| }; |
| |
| } // namespace media |
| |
| #endif //MEDIA_BASE_MOCK_TASK_H_ |