aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/gmock/gmock-generated-function-mockers.h111
-rw-r--r--include/gmock/gmock-generated-function-mockers.h.pump49
-rw-r--r--test/gmock-generated-function-mockers_test.cc44
3 files changed, 204 insertions, 0 deletions
diff --git a/include/gmock/gmock-generated-function-mockers.h b/include/gmock/gmock-generated-function-mockers.h
index b6c1d82e..3002b6c5 100644
--- a/include/gmock/gmock-generated-function-mockers.h
+++ b/include/gmock/gmock-generated-function-mockers.h
@@ -712,6 +712,117 @@ using internal::FunctionMocker;
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, F) \
GMOCK_METHOD10_(typename, const, ct, m, F)
+// A MockFunction<F> class has one mock method whose type is F. It is
+// useful when you just want your test code to emit some messages and
+// have Google Mock verify the right messages are sent (and perhaps at
+// the right times). For example, if you are exercising code:
+//
+// 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:
+//
+// TEST(FooTest, InvokesBarCorrectly) {
+// MyMock mock;
+// MockFunction<void(string check_point_name)> 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().
+template <typename F>
+class MockFunction;
+
+template <typename R>
+class MockFunction<R()> {
+ public:
+ MOCK_METHOD0_T(Call, R());
+};
+
+template <typename R, typename A0>
+class MockFunction<R(A0)> {
+ public:
+ MOCK_METHOD1_T(Call, R(A0));
+};
+
+template <typename R, typename A0, typename A1>
+class MockFunction<R(A0, A1)> {
+ public:
+ MOCK_METHOD2_T(Call, R(A0, A1));
+};
+
+template <typename R, typename A0, typename A1, typename A2>
+class MockFunction<R(A0, A1, A2)> {
+ public:
+ MOCK_METHOD3_T(Call, R(A0, A1, A2));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+class MockFunction<R(A0, A1, A2, A3)> {
+ public:
+ MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4>
+class MockFunction<R(A0, A1, A2, A3, A4)> {
+ public:
+ MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5>
+class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
+ public:
+ MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
+ public:
+ MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
+ public:
+ MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
+ public:
+ MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
+};
+
+template <typename R, typename A0, typename A1, typename A2, typename A3,
+ typename A4, typename A5, typename A6, typename A7, typename A8,
+ typename A9>
+class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
+ public:
+ MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
+};
+
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/include/gmock/gmock-generated-function-mockers.h.pump b/include/gmock/gmock-generated-function-mockers.h.pump
index 54b848f6..3c845632 100644
--- a/include/gmock/gmock-generated-function-mockers.h.pump
+++ b/include/gmock/gmock-generated-function-mockers.h.pump
@@ -198,6 +198,55 @@ $for i [[
]]
+// A MockFunction<F> class has one mock method whose type is F. It is
+// useful when you just want your test code to emit some messages and
+// have Google Mock verify the right messages are sent (and perhaps at
+// the right times). For example, if you are exercising code:
+//
+// 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:
+//
+// TEST(FooTest, InvokesBarCorrectly) {
+// MyMock mock;
+// MockFunction<void(string check_point_name)> 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().
+template <typename F>
+class MockFunction;
+
+
+$for i [[
+$range j 0..i-1
+template <typename R$for j [[, typename A$j]]>
+class MockFunction<R($for j, [[A$j]])> {
+ public:
+ MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]]));
+};
+
+
+]]
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/test/gmock-generated-function-mockers_test.cc b/test/gmock-generated-function-mockers_test.cc
index 7267c10e..1ce8c451 100644
--- a/test/gmock-generated-function-mockers_test.cc
+++ b/test/gmock-generated-function-mockers_test.cc
@@ -66,6 +66,7 @@ using testing::Const;
using testing::DoDefault;
using testing::Eq;
using testing::Lt;
+using testing::MockFunction;
using testing::Ref;
using testing::Return;
using testing::ReturnRef;
@@ -462,5 +463,48 @@ TEST(OverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {
EXPECT_EQ(3, const_mock->Overloaded(1));
}
+TEST(MockFunctionTest, WorksForVoidNullary) {
+ MockFunction<void()> foo;
+ EXPECT_CALL(foo, Call());
+ foo.Call();
+}
+
+TEST(MockFunctionTest, WorksForNonVoidNullary) {
+ MockFunction<int()> foo;
+ EXPECT_CALL(foo, Call())
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+ EXPECT_EQ(1, foo.Call());
+ EXPECT_EQ(2, foo.Call());
+}
+
+TEST(MockFunctionTest, WorksForVoidUnary) {
+ MockFunction<void(int)> foo;
+ EXPECT_CALL(foo, Call(1));
+ foo.Call(1);
+}
+
+TEST(MockFunctionTest, WorksForNonVoidBinary) {
+ MockFunction<int(bool, int)> foo;
+ EXPECT_CALL(foo, Call(false, 42))
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+ EXPECT_CALL(foo, Call(true, Ge(100)))
+ .WillOnce(Return(3));
+ EXPECT_EQ(1, foo.Call(false, 42));
+ EXPECT_EQ(2, foo.Call(false, 42));
+ EXPECT_EQ(3, foo.Call(true, 120));
+}
+
+TEST(MockFunctionTest, WorksFor10Arguments) {
+ MockFunction<int(bool a0, char a1, int a2, int a3, int a4,
+ int a5, int a6, char a7, int a8, bool a9)> foo;
+ EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _))
+ .WillOnce(Return(1))
+ .WillOnce(Return(2));
+ EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true));
+ EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));
+}
+
} // namespace gmock_generated_function_mockers_test
} // namespace testing