| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "dbus/message.h" | 10 #include "dbus/message.h" |
| 11 #include "dbus/mock_bus.h" | 11 #include "dbus/mock_bus.h" |
| 12 #include "dbus/mock_object_proxy.h" | 12 #include "dbus/mock_object_proxy.h" |
| 13 #include "dbus/mock_exported_object.h" | 13 #include "dbus/mock_exported_object.h" |
| 14 #include "dbus/object_path.h" | 14 #include "dbus/object_path.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using ::testing::_; | 18 using ::testing::_; |
| 19 using ::testing::Invoke; | 19 using ::testing::Invoke; |
| 20 using ::testing::Return; | 20 using ::testing::Return; |
| 21 using ::testing::Unused; | 21 using ::testing::Unused; |
| 22 | 22 |
| 23 namespace dbus { |
| 24 |
| 23 class MockTest : public testing::Test { | 25 class MockTest : public testing::Test { |
| 24 public: | 26 public: |
| 25 MockTest() { | 27 MockTest() { |
| 26 } | 28 } |
| 27 | 29 |
| 28 virtual void SetUp() { | 30 virtual void SetUp() { |
| 29 // Create a mock bus. | 31 // Create a mock bus. |
| 30 dbus::Bus::Options options; | 32 Bus::Options options; |
| 31 options.bus_type = dbus::Bus::SYSTEM; | 33 options.bus_type = Bus::SYSTEM; |
| 32 mock_bus_ = new dbus::MockBus(options); | 34 mock_bus_ = new MockBus(options); |
| 33 | 35 |
| 34 // Create a mock proxy. | 36 // Create a mock proxy. |
| 35 mock_proxy_ = new dbus::MockObjectProxy( | 37 mock_proxy_ = new MockObjectProxy( |
| 36 mock_bus_.get(), | 38 mock_bus_.get(), |
| 37 "org.chromium.TestService", | 39 "org.chromium.TestService", |
| 38 dbus::ObjectPath("/org/chromium/TestObject")); | 40 ObjectPath("/org/chromium/TestObject")); |
| 39 | 41 |
| 40 // Set an expectation so mock_proxy's CallMethodAndBlock() will use | 42 // Set an expectation so mock_proxy's CallMethodAndBlock() will use |
| 41 // CreateMockProxyResponse() to return responses. | 43 // CreateMockProxyResponse() to return responses. |
| 42 EXPECT_CALL(*mock_proxy_.get(), MockCallMethodAndBlock(_, _)) | 44 EXPECT_CALL(*mock_proxy_.get(), MockCallMethodAndBlock(_, _)) |
| 43 .WillRepeatedly(Invoke(this, &MockTest::CreateMockProxyResponse)); | 45 .WillRepeatedly(Invoke(this, &MockTest::CreateMockProxyResponse)); |
| 44 | 46 |
| 45 // Set an expectation so mock_proxy's CallMethod() will use | 47 // Set an expectation so mock_proxy's CallMethod() will use |
| 46 // HandleMockProxyResponseWithMessageLoop() to return responses. | 48 // HandleMockProxyResponseWithMessageLoop() to return responses. |
| 47 EXPECT_CALL(*mock_proxy_.get(), CallMethod(_, _, _)).WillRepeatedly( | 49 EXPECT_CALL(*mock_proxy_.get(), CallMethod(_, _, _)).WillRepeatedly( |
| 48 Invoke(this, &MockTest::HandleMockProxyResponseWithMessageLoop)); | 50 Invoke(this, &MockTest::HandleMockProxyResponseWithMessageLoop)); |
| 49 | 51 |
| 50 // Set an expectation so mock_bus's GetObjectProxy() for the given | 52 // Set an expectation so mock_bus's GetObjectProxy() for the given |
| 51 // service name and the object path will return mock_proxy_. | 53 // service name and the object path will return mock_proxy_. |
| 52 EXPECT_CALL(*mock_bus_.get(), | 54 EXPECT_CALL(*mock_bus_.get(), |
| 53 GetObjectProxy("org.chromium.TestService", | 55 GetObjectProxy("org.chromium.TestService", |
| 54 dbus::ObjectPath("/org/chromium/TestObject"))) | 56 ObjectPath("/org/chromium/TestObject"))) |
| 55 .WillOnce(Return(mock_proxy_.get())); | 57 .WillOnce(Return(mock_proxy_.get())); |
| 56 | 58 |
| 57 // ShutdownAndBlock() will be called in TearDown(). | 59 // ShutdownAndBlock() will be called in TearDown(). |
| 58 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); | 60 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); |
| 59 } | 61 } |
| 60 | 62 |
| 61 virtual void TearDown() { | 63 virtual void TearDown() { |
| 62 mock_bus_->ShutdownAndBlock(); | 64 mock_bus_->ShutdownAndBlock(); |
| 63 } | 65 } |
| 64 | 66 |
| 65 // Called when the response is received. | 67 // Called when the response is received. |
| 66 void OnResponse(dbus::Response* response) { | 68 void OnResponse(Response* response) { |
| 67 // |response| will be deleted on exit of the function. Copy the | 69 // |response| will be deleted on exit of the function. Copy the |
| 68 // payload to |response_string_|. | 70 // payload to |response_string_|. |
| 69 if (response) { | 71 if (response) { |
| 70 dbus::MessageReader reader(response); | 72 MessageReader reader(response); |
| 71 ASSERT_TRUE(reader.PopString(&response_string_)); | 73 ASSERT_TRUE(reader.PopString(&response_string_)); |
| 72 } | 74 } |
| 73 message_loop_.Quit(); | 75 message_loop_.Quit(); |
| 74 }; | 76 }; |
| 75 | 77 |
| 76 protected: | 78 protected: |
| 77 std::string response_string_; | 79 std::string response_string_; |
| 78 base::MessageLoop message_loop_; | 80 base::MessageLoop message_loop_; |
| 79 scoped_refptr<dbus::MockBus> mock_bus_; | 81 scoped_refptr<MockBus> mock_bus_; |
| 80 scoped_refptr<dbus::MockObjectProxy> mock_proxy_; | 82 scoped_refptr<MockObjectProxy> mock_proxy_; |
| 81 | 83 |
| 82 private: | 84 private: |
| 83 // Returns a response for the given method call. Used to implement | 85 // Returns a response for the given method call. Used to implement |
| 84 // CallMethodAndBlock() for |mock_proxy_|. | 86 // CallMethodAndBlock() for |mock_proxy_|. |
| 85 dbus::Response* CreateMockProxyResponse(dbus::MethodCall* method_call, | 87 Response* CreateMockProxyResponse(MethodCall* method_call, |
| 86 int timeout_ms) { | 88 int timeout_ms) { |
| 87 if (method_call->GetInterface() == "org.chromium.TestInterface" && | 89 if (method_call->GetInterface() == "org.chromium.TestInterface" && |
| 88 method_call->GetMember() == "Echo") { | 90 method_call->GetMember() == "Echo") { |
| 89 dbus::MessageReader reader(method_call); | 91 MessageReader reader(method_call); |
| 90 std::string text_message; | 92 std::string text_message; |
| 91 if (reader.PopString(&text_message)) { | 93 if (reader.PopString(&text_message)) { |
| 92 scoped_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); | 94 scoped_ptr<Response> response = Response::CreateEmpty(); |
| 93 dbus::MessageWriter writer(response.get()); | 95 MessageWriter writer(response.get()); |
| 94 writer.AppendString(text_message); | 96 writer.AppendString(text_message); |
| 95 return response.release(); | 97 return response.release(); |
| 96 } | 98 } |
| 97 } | 99 } |
| 98 | 100 |
| 99 LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); | 101 LOG(ERROR) << "Unexpected method call: " << method_call->ToString(); |
| 100 return NULL; | 102 return NULL; |
| 101 } | 103 } |
| 102 | 104 |
| 103 // Creates a response and runs the given response callback in the | 105 // Creates a response and runs the given response callback in the |
| 104 // message loop with the response. Used to implement for |mock_proxy_|. | 106 // message loop with the response. Used to implement for |mock_proxy_|. |
| 105 void HandleMockProxyResponseWithMessageLoop( | 107 void HandleMockProxyResponseWithMessageLoop( |
| 106 dbus::MethodCall* method_call, | 108 MethodCall* method_call, |
| 107 int timeout_ms, | 109 int timeout_ms, |
| 108 dbus::ObjectProxy::ResponseCallback response_callback) { | 110 ObjectProxy::ResponseCallback response_callback) { |
| 109 dbus::Response* response = CreateMockProxyResponse(method_call, | 111 Response* response = CreateMockProxyResponse(method_call, timeout_ms); |
| 110 timeout_ms); | |
| 111 message_loop_.PostTask(FROM_HERE, | 112 message_loop_.PostTask(FROM_HERE, |
| 112 base::Bind(&MockTest::RunResponseCallback, | 113 base::Bind(&MockTest::RunResponseCallback, |
| 113 base::Unretained(this), | 114 base::Unretained(this), |
| 114 response_callback, | 115 response_callback, |
| 115 response)); | 116 response)); |
| 116 } | 117 } |
| 117 | 118 |
| 118 // Runs the given response callback with the given response. | 119 // Runs the given response callback with the given response. |
| 119 void RunResponseCallback( | 120 void RunResponseCallback( |
| 120 dbus::ObjectProxy::ResponseCallback response_callback, | 121 ObjectProxy::ResponseCallback response_callback, |
| 121 dbus::Response* response) { | 122 Response* response) { |
| 122 response_callback.Run(response); | 123 response_callback.Run(response); |
| 123 delete response; | 124 delete response; |
| 124 } | 125 } |
| 125 }; | 126 }; |
| 126 | 127 |
| 127 // This test demonstrates how to mock a synchronos method call using the | 128 // This test demonstrates how to mock a synchronos method call using the |
| 128 // mock classes. | 129 // mock classes. |
| 129 TEST_F(MockTest, CallMethodAndBlock) { | 130 TEST_F(MockTest, CallMethodAndBlock) { |
| 130 const char kHello[] = "Hello"; | 131 const char kHello[] = "Hello"; |
| 131 // Get an object proxy from the mock bus. | 132 // Get an object proxy from the mock bus. |
| 132 dbus::ObjectProxy* proxy = mock_bus_->GetObjectProxy( | 133 ObjectProxy* proxy = mock_bus_->GetObjectProxy( |
| 133 "org.chromium.TestService", | 134 "org.chromium.TestService", |
| 134 dbus::ObjectPath("/org/chromium/TestObject")); | 135 ObjectPath("/org/chromium/TestObject")); |
| 135 | 136 |
| 136 // Create a method call. | 137 // Create a method call. |
| 137 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 138 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
| 138 dbus::MessageWriter writer(&method_call); | 139 MessageWriter writer(&method_call); |
| 139 writer.AppendString(kHello); | 140 writer.AppendString(kHello); |
| 140 | 141 |
| 141 // Call the method. | 142 // Call the method. |
| 142 scoped_ptr<dbus::Response> response( | 143 scoped_ptr<Response> response( |
| 143 proxy->CallMethodAndBlock(&method_call, | 144 proxy->CallMethodAndBlock(&method_call, |
| 144 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | 145 ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 145 | 146 |
| 146 // Check the response. | 147 // Check the response. |
| 147 ASSERT_TRUE(response.get()); | 148 ASSERT_TRUE(response.get()); |
| 148 dbus::MessageReader reader(response.get()); | 149 MessageReader reader(response.get()); |
| 149 std::string text_message; | 150 std::string text_message; |
| 150 ASSERT_TRUE(reader.PopString(&text_message)); | 151 ASSERT_TRUE(reader.PopString(&text_message)); |
| 151 // The text message should be echo'ed back. | 152 // The text message should be echo'ed back. |
| 152 EXPECT_EQ(kHello, text_message); | 153 EXPECT_EQ(kHello, text_message); |
| 153 } | 154 } |
| 154 | 155 |
| 155 // This test demonstrates how to mock an asynchronos method call using the | 156 // This test demonstrates how to mock an asynchronos method call using the |
| 156 // mock classes. | 157 // mock classes. |
| 157 TEST_F(MockTest, CallMethod) { | 158 TEST_F(MockTest, CallMethod) { |
| 158 const char kHello[] = "hello"; | 159 const char kHello[] = "hello"; |
| 159 | 160 |
| 160 // Get an object proxy from the mock bus. | 161 // Get an object proxy from the mock bus. |
| 161 dbus::ObjectProxy* proxy = mock_bus_->GetObjectProxy( | 162 ObjectProxy* proxy = mock_bus_->GetObjectProxy( |
| 162 "org.chromium.TestService", | 163 "org.chromium.TestService", |
| 163 dbus::ObjectPath("/org/chromium/TestObject")); | 164 ObjectPath("/org/chromium/TestObject")); |
| 164 | 165 |
| 165 // Create a method call. | 166 // Create a method call. |
| 166 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 167 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
| 167 dbus::MessageWriter writer(&method_call); | 168 MessageWriter writer(&method_call); |
| 168 writer.AppendString(kHello); | 169 writer.AppendString(kHello); |
| 169 | 170 |
| 170 // Call the method. | 171 // Call the method. |
| 171 proxy->CallMethod(&method_call, | 172 proxy->CallMethod(&method_call, |
| 172 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 173 ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 173 base::Bind(&MockTest::OnResponse, | 174 base::Bind(&MockTest::OnResponse, |
| 174 base::Unretained(this))); | 175 base::Unretained(this))); |
| 175 // Run the message loop to let OnResponse be called. | 176 // Run the message loop to let OnResponse be called. |
| 176 message_loop_.Run(); | 177 message_loop_.Run(); |
| 177 | 178 |
| 178 EXPECT_EQ(kHello, response_string_); | 179 EXPECT_EQ(kHello, response_string_); |
| 179 } | 180 } |
| 181 |
| 182 } // namespace dbus |
| OLD | NEW |