Googletest export
Move FunctionMocker and MockFunction out of the pump file and implement with variadic templates. PiperOrigin-RevId: 220640265
This commit is contained in:
parent
105579a6e4
commit
de5be0eb28
@ -52,281 +52,6 @@
|
||||
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
template <typename R>
|
||||
class FunctionMocker<R()> : public
|
||||
internal::FunctionMockerBase<R()> {
|
||||
public:
|
||||
typedef R F();
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With() {
|
||||
return MockSpec<F>(this, ::std::make_tuple());
|
||||
}
|
||||
|
||||
R Invoke() {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1>
|
||||
class FunctionMocker<R(A1)> : public
|
||||
internal::FunctionMockerBase<R(A1)> {
|
||||
public:
|
||||
typedef R F(A1);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
class FunctionMocker<R(A1, A2)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2)> {
|
||||
public:
|
||||
typedef R F(A1, A2);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3>
|
||||
class FunctionMocker<R(A1, A2, A3)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4>
|
||||
class FunctionMocker<R(A1, A2, A3, A4)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4, m5));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4),
|
||||
std::forward<A5>(a5)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4, m5, m6));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4),
|
||||
std::forward<A5>(a5), std::forward<A6>(a6)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4, m5, m6, m7));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4),
|
||||
std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4, m5, m6, m7, m8));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4),
|
||||
std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7),
|
||||
std::forward<A8>(a8)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4, m5, m6, m7, m8,
|
||||
m9));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4),
|
||||
std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7),
|
||||
std::forward<A8>(a8), std::forward<A9>(a9)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2, typename A3, typename A4,
|
||||
typename A5, typename A6, typename A7, typename A8, typename A9,
|
||||
typename A10>
|
||||
class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
|
||||
internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
|
||||
public:
|
||||
typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With(const Matcher<A1>& m1, const Matcher<A2>& m2,
|
||||
const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
|
||||
const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
|
||||
const Matcher<A9>& m9, const Matcher<A10>& m10) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(m1, m2, m3, m4, m5, m6, m7, m8,
|
||||
m9, m10));
|
||||
}
|
||||
|
||||
R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
|
||||
A10 a10) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple(std::forward<A1>(a1),
|
||||
std::forward<A2>(a2), std::forward<A3>(a3), std::forward<A4>(a4),
|
||||
std::forward<A5>(a5), std::forward<A6>(a6), std::forward<A7>(a7),
|
||||
std::forward<A8>(a8), std::forward<A9>(a9), std::forward<A10>(a10)));
|
||||
}
|
||||
};
|
||||
|
||||
// Removes the given pointer; this is a helper for the expectation setter method
|
||||
// for parameterless matchers.
|
||||
//
|
||||
@ -1036,293 +761,6 @@ using internal::FunctionMocker;
|
||||
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
|
||||
GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
|
||||
|
||||
// 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().
|
||||
//
|
||||
// MockFunction<F> can also be used to exercise code that accepts
|
||||
// std::function<F> callbacks. To do so, use AsStdFunction() method
|
||||
// to create std::function proxy forwarding to original object's Call.
|
||||
// Example:
|
||||
//
|
||||
// TEST(FooTest, RunsCallbackWithBarArgument) {
|
||||
// MockFunction<int(string)> callback;
|
||||
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
|
||||
// Foo(callback.AsStdFunction());
|
||||
// }
|
||||
template <typename F>
|
||||
class MockFunction;
|
||||
|
||||
template <typename R>
|
||||
class MockFunction<R()> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD0_T(Call, R());
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R()> AsStdFunction() {
|
||||
return [this]() -> R {
|
||||
return this->Call();
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0>
|
||||
class MockFunction<R(A0)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD1_T(Call, R(A0));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0)> AsStdFunction() {
|
||||
return [this](A0 a0) -> R {
|
||||
return this->Call(::std::forward<A0>(a0));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1>
|
||||
class MockFunction<R(A0, A1)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD2_T(Call, R(A0, A1));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2>
|
||||
class MockFunction<R(A0, A1, A2)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD3_T(Call, R(A0, A1, A2));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3>
|
||||
class MockFunction<R(A0, A1, A2, A3)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
template <typename R, typename A0, typename A1, typename A2, typename A3,
|
||||
typename A4>
|
||||
class MockFunction<R(A0, A1, A2, A3, A4)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3),
|
||||
::std::forward<A4>(a4));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
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:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3),
|
||||
::std::forward<A4>(a4), ::std::forward<A5>(a5));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
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:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3),
|
||||
::std::forward<A4>(a4), ::std::forward<A5>(a5),
|
||||
::std::forward<A6>(a6));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
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:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3),
|
||||
::std::forward<A4>(a4), ::std::forward<A5>(a5),
|
||||
::std::forward<A6>(a6), ::std::forward<A7>(a7));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
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:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
|
||||
A8 a8) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3),
|
||||
::std::forward<A4>(a4), ::std::forward<A5>(a5),
|
||||
::std::forward<A6>(a6), ::std::forward<A7>(a7),
|
||||
::std::forward<A8>(a8));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
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:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() {
|
||||
return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
|
||||
A8 a8, A9 a9) -> R {
|
||||
return this->Call(::std::forward<A0>(a0), ::std::forward<A1>(a1),
|
||||
::std::forward<A2>(a2), ::std::forward<A3>(a3),
|
||||
::std::forward<A4>(a4), ::std::forward<A5>(a5),
|
||||
::std::forward<A6>(a6), ::std::forward<A7>(a7),
|
||||
::std::forward<A8>(a8), ::std::forward<A9>(a9));
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
|
@ -54,49 +54,7 @@ $var n = 10 $$ The maximum arity we support.
|
||||
namespace testing {
|
||||
namespace internal {
|
||||
|
||||
template <typename F>
|
||||
class FunctionMockerBase;
|
||||
|
||||
// Note: class FunctionMocker really belongs to the ::testing
|
||||
// namespace. However if we define it in ::testing, MSVC will
|
||||
// complain when classes in ::testing::internal declare it as a
|
||||
// friend class template. To workaround this compiler bug, we define
|
||||
// FunctionMocker in ::testing::internal and import it into ::testing.
|
||||
template <typename F>
|
||||
class FunctionMocker;
|
||||
|
||||
|
||||
$range i 0..n
|
||||
$for i [[
|
||||
$range j 1..i
|
||||
$var typename_As = [[$for j [[, typename A$j]]]]
|
||||
$var As = [[$for j, [[A$j]]]]
|
||||
$var as = [[$for j, [[std::forward<A$j>(a$j)]]]]
|
||||
$var Aas = [[$for j, [[A$j a$j]]]]
|
||||
$var ms = [[$for j, [[m$j]]]]
|
||||
$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
|
||||
template <typename R$typename_As>
|
||||
class FunctionMocker<R($As)> : public
|
||||
internal::FunctionMockerBase<R($As)> {
|
||||
public:
|
||||
typedef R F($As);
|
||||
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
|
||||
|
||||
MockSpec<F> With($matchers) {
|
||||
return MockSpec<F>(this, ::std::make_tuple($ms));
|
||||
}
|
||||
|
||||
R Invoke($Aas) {
|
||||
// Even though gcc and MSVC don't enforce it, 'this->' is required
|
||||
// by the C++ standard [14.6.4] here, as the base class type is
|
||||
// dependent on the template argument (and thus shouldn't be
|
||||
// looked into when resolving InvokeWith).
|
||||
return this->InvokeWith(ArgumentTuple($as));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
// Removes the given pointer; this is a helper for the expectation setter method
|
||||
// for parameterless matchers.
|
||||
//
|
||||
@ -269,82 +227,6 @@ $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().
|
||||
//
|
||||
// MockFunction<F> can also be used to exercise code that accepts
|
||||
// std::function<F> callbacks. To do so, use AsStdFunction() method
|
||||
// to create std::function proxy forwarding to original object's Call.
|
||||
// Example:
|
||||
//
|
||||
// TEST(FooTest, RunsCallbackWithBarArgument) {
|
||||
// MockFunction<int(string)> callback;
|
||||
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
|
||||
// Foo(callback.AsStdFunction());
|
||||
// }
|
||||
template <typename F>
|
||||
class MockFunction;
|
||||
|
||||
|
||||
$for i [[
|
||||
$range j 0..i-1
|
||||
$var ArgTypes = [[$for j, [[A$j]]]]
|
||||
$var ArgValues = [[$for j, [[::std::forward<A$j>(a$j)]]]]
|
||||
$var ArgDecls = [[$for j, [[A$j a$j]]]]
|
||||
template <typename R$for j [[, typename A$j]]>
|
||||
class MockFunction<R($ArgTypes)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
|
||||
MOCK_METHOD$i[[]]_T(Call, R($ArgTypes));
|
||||
|
||||
#if GTEST_HAS_STD_FUNCTION_
|
||||
::std::function<R($ArgTypes)> AsStdFunction() {
|
||||
return [this]($ArgDecls) -> R {
|
||||
return this->Call($ArgValues);
|
||||
};
|
||||
}
|
||||
#endif // GTEST_HAS_STD_FUNCTION_
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
|
||||
};
|
||||
|
||||
|
||||
]]
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
|
||||
|
@ -106,9 +106,6 @@ template <typename F> class TypedExpectation;
|
||||
// Helper class for testing the Expectation class template.
|
||||
class ExpectationTester;
|
||||
|
||||
// Base class for function mockers.
|
||||
template <typename F> class FunctionMockerBase;
|
||||
|
||||
// Protects the mock object registry (in class Mock), all function
|
||||
// mockers, and all expectations.
|
||||
//
|
||||
@ -125,9 +122,9 @@ GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex);
|
||||
// Untyped base class for ActionResultHolder<R>.
|
||||
class UntypedActionResultHolderBase;
|
||||
|
||||
// Abstract base class of FunctionMockerBase. This is the
|
||||
// Abstract base class of FunctionMocker. This is the
|
||||
// type-agnostic part of the function mocker interface. Its pure
|
||||
// virtual methods are implemented by FunctionMockerBase.
|
||||
// virtual methods are implemented by FunctionMocker.
|
||||
class GTEST_API_ UntypedFunctionMockerBase {
|
||||
public:
|
||||
UntypedFunctionMockerBase();
|
||||
@ -415,7 +412,7 @@ class GTEST_API_ Mock {
|
||||
// Needed for a function mocker to register itself (so that we know
|
||||
// how to clear a mock object).
|
||||
template <typename F>
|
||||
friend class internal::FunctionMockerBase;
|
||||
friend class internal::FunctionMocker;
|
||||
|
||||
template <typename M>
|
||||
friend class NiceMock;
|
||||
@ -478,7 +475,7 @@ class GTEST_API_ Mock {
|
||||
// Unregisters a mock method; removes the owning mock object from
|
||||
// the registry when the last mock method associated with it has
|
||||
// been unregistered. This is called only in the destructor of
|
||||
// FunctionMockerBase.
|
||||
// FunctionMocker.
|
||||
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
|
||||
}; // class Mock
|
||||
@ -534,7 +531,7 @@ class GTEST_API_ Expectation {
|
||||
friend class ::testing::internal::UntypedFunctionMockerBase;
|
||||
|
||||
template <typename F>
|
||||
friend class ::testing::internal::FunctionMockerBase;
|
||||
friend class ::testing::internal::FunctionMocker;
|
||||
|
||||
template <typename F>
|
||||
friend class ::testing::internal::TypedExpectation;
|
||||
@ -893,7 +890,7 @@ class TypedExpectation : public ExpectationBase {
|
||||
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
|
||||
typedef typename Function<F>::Result Result;
|
||||
|
||||
TypedExpectation(FunctionMockerBase<F>* owner, const char* a_file, int a_line,
|
||||
TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,
|
||||
const std::string& a_source_text,
|
||||
const ArgumentMatcherTuple& m)
|
||||
: ExpectationBase(a_file, a_line, a_source_text),
|
||||
@ -1082,7 +1079,7 @@ class TypedExpectation : public ExpectationBase {
|
||||
|
||||
private:
|
||||
template <typename Function>
|
||||
friend class FunctionMockerBase;
|
||||
friend class FunctionMocker;
|
||||
|
||||
// Returns an Expectation object that references and co-owns this
|
||||
// expectation.
|
||||
@ -1161,8 +1158,7 @@ class TypedExpectation : public ExpectationBase {
|
||||
}
|
||||
|
||||
// Returns the action that should be taken for the current invocation.
|
||||
const Action<F>& GetCurrentAction(
|
||||
const FunctionMockerBase<F>* mocker,
|
||||
const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,
|
||||
const ArgumentTuple& args) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
@ -1199,8 +1195,7 @@ class TypedExpectation : public ExpectationBase {
|
||||
// Mock does it to 'why'. This method is not const as it calls
|
||||
// IncrementCallCount(). A return value of NULL means the default
|
||||
// action.
|
||||
const Action<F>* GetActionForArguments(
|
||||
const FunctionMockerBase<F>* mocker,
|
||||
const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,
|
||||
const ArgumentTuple& args,
|
||||
::std::ostream* what,
|
||||
::std::ostream* why)
|
||||
@ -1233,7 +1228,7 @@ class TypedExpectation : public ExpectationBase {
|
||||
|
||||
// All the fields below won't change once the EXPECT_CALL()
|
||||
// statement finishes.
|
||||
FunctionMockerBase<F>* const owner_;
|
||||
FunctionMocker<F>* const owner_;
|
||||
ArgumentMatcherTuple matchers_;
|
||||
Matcher<const ArgumentTuple&> extra_matcher_;
|
||||
Action<F> repeated_action_;
|
||||
@ -1265,7 +1260,7 @@ class MockSpec {
|
||||
|
||||
// Constructs a MockSpec object, given the function mocker object
|
||||
// that the spec is associated with.
|
||||
MockSpec(internal::FunctionMockerBase<F>* function_mocker,
|
||||
MockSpec(internal::FunctionMocker<F>* function_mocker,
|
||||
const ArgumentMatcherTuple& matchers)
|
||||
: function_mocker_(function_mocker), matchers_(matchers) {}
|
||||
|
||||
@ -1301,7 +1296,7 @@ class MockSpec {
|
||||
friend class internal::FunctionMocker;
|
||||
|
||||
// The function mocker that owns this spec.
|
||||
internal::FunctionMockerBase<F>* const function_mocker_;
|
||||
internal::FunctionMocker<F>* const function_mocker_;
|
||||
// The argument matchers specified in the spec.
|
||||
ArgumentMatcherTuple matchers_;
|
||||
|
||||
@ -1402,7 +1397,7 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
|
||||
// result in a new-ed ActionResultHolder.
|
||||
template <typename F>
|
||||
static ActionResultHolder* PerformDefaultAction(
|
||||
const FunctionMockerBase<F>* func_mocker,
|
||||
const FunctionMocker<F>* func_mocker,
|
||||
typename Function<F>::ArgumentTuple&& args,
|
||||
const std::string& call_description) {
|
||||
return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
|
||||
@ -1442,7 +1437,7 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
|
||||
// of an empty ActionResultHolder*.
|
||||
template <typename F>
|
||||
static ActionResultHolder* PerformDefaultAction(
|
||||
const FunctionMockerBase<F>* func_mocker,
|
||||
const FunctionMocker<F>* func_mocker,
|
||||
typename Function<F>::ArgumentTuple&& args,
|
||||
const std::string& call_description) {
|
||||
func_mocker->PerformDefaultAction(std::move(args), call_description);
|
||||
@ -1463,22 +1458,39 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
|
||||
};
|
||||
|
||||
// The base of the function mocker class for the given function type.
|
||||
// We put the methods in this class instead of its child to avoid code
|
||||
// bloat.
|
||||
template <typename F>
|
||||
class FunctionMockerBase : public UntypedFunctionMockerBase {
|
||||
public:
|
||||
typedef typename Function<F>::Result Result;
|
||||
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
|
||||
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
|
||||
class FunctionMocker;
|
||||
|
||||
FunctionMockerBase() {}
|
||||
template <typename R, typename... Args>
|
||||
class FunctionMocker<R(Args...)> : public UntypedFunctionMockerBase {
|
||||
using F = R(Args...);
|
||||
|
||||
public:
|
||||
using Result = R;
|
||||
using ArgumentTuple = std::tuple<Args...>;
|
||||
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
|
||||
|
||||
FunctionMocker() {}
|
||||
|
||||
// There is no generally useful and implementable semantics of
|
||||
// copying a mock object, so copying a mock is usually a user error.
|
||||
// Thus we disallow copying function mockers. If the user really
|
||||
// wants to copy a mock object, they should implement their own copy
|
||||
// operation, for example:
|
||||
//
|
||||
// class MockFoo : public Foo {
|
||||
// public:
|
||||
// // Defines a copy constructor explicitly.
|
||||
// MockFoo(const MockFoo& src) {}
|
||||
// ...
|
||||
// };
|
||||
FunctionMocker(const FunctionMocker&) = delete;
|
||||
FunctionMocker& operator=(const FunctionMocker&) = delete;
|
||||
|
||||
// The destructor verifies that all expectations on this mock
|
||||
// function have been satisfied. If not, it will report Google Test
|
||||
// non-fatal failures for the violations.
|
||||
virtual ~FunctionMockerBase()
|
||||
virtual ~FunctionMocker()
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
MutexLock l(&g_gmock_mutex);
|
||||
VerifyAndClearExpectationsLocked();
|
||||
@ -1509,7 +1521,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
||||
// mutable state of this object, and thus can be called concurrently
|
||||
// without locking.
|
||||
// L = *
|
||||
Result PerformDefaultAction(typename Function<F>::ArgumentTuple&& args,
|
||||
Result PerformDefaultAction(ArgumentTuple&& args,
|
||||
const std::string& call_description) const {
|
||||
const OnCallSpec<F>* const spec =
|
||||
this->FindOnCallSpec(args);
|
||||
@ -1584,25 +1596,26 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
||||
g_gmock_mutex.Lock();
|
||||
}
|
||||
|
||||
// Returns the result of invoking this mock function with the given
|
||||
// arguments. This function can be safely called from multiple
|
||||
// threads concurrently.
|
||||
Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
ArgumentTuple tuple(std::forward<Args>(args)...);
|
||||
std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>(
|
||||
this->UntypedInvokeWith(static_cast<void*>(&tuple))));
|
||||
return holder->Unwrap();
|
||||
}
|
||||
|
||||
MockSpec<F> With(Matcher<Args>... m) {
|
||||
return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename Function>
|
||||
friend class MockSpec;
|
||||
|
||||
typedef ActionResultHolder<Result> ResultHolder;
|
||||
|
||||
// Returns the result of invoking this mock function with the given
|
||||
// arguments. This function can be safely called from multiple
|
||||
// threads concurrently.
|
||||
Result InvokeWith(typename Function<F>::ArgumentTuple&& args)
|
||||
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
|
||||
// const_cast is required since in C++98 we still pass ArgumentTuple around
|
||||
// by const& instead of rvalue reference.
|
||||
void* untyped_args = const_cast<void*>(static_cast<const void*>(&args));
|
||||
std::unique_ptr<ResultHolder> holder(
|
||||
DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args)));
|
||||
return holder->Unwrap();
|
||||
}
|
||||
|
||||
// Adds and returns a default action spec for this mock function.
|
||||
OnCallSpec<F>& AddNewOnCallSpec(
|
||||
const char* file, int line,
|
||||
@ -1779,36 +1792,98 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
|
||||
expectation->DescribeCallCountTo(why);
|
||||
}
|
||||
}
|
||||
|
||||
// There is no generally useful and implementable semantics of
|
||||
// copying a mock object, so copying a mock is usually a user error.
|
||||
// Thus we disallow copying function mockers. If the user really
|
||||
// wants to copy a mock object, they should implement their own copy
|
||||
// operation, for example:
|
||||
//
|
||||
// class MockFoo : public Foo {
|
||||
// public:
|
||||
// // Defines a copy constructor explicitly.
|
||||
// MockFoo(const MockFoo& src) {}
|
||||
// ...
|
||||
// };
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase);
|
||||
}; // class FunctionMockerBase
|
||||
}; // class FunctionMocker
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
|
||||
|
||||
// Implements methods of FunctionMockerBase.
|
||||
|
||||
// Verifies that all expectations on this mock function have been
|
||||
// satisfied. Reports one or more Google Test non-fatal failures and
|
||||
// returns false if not.
|
||||
|
||||
// Reports an uninteresting call (whose description is in msg) in the
|
||||
// manner specified by 'reaction'.
|
||||
void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// 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().
|
||||
//
|
||||
// MockFunction<F> can also be used to exercise code that accepts
|
||||
// std::function<F> callbacks. To do so, use AsStdFunction() method
|
||||
// to create std::function proxy forwarding to original object's Call.
|
||||
// Example:
|
||||
//
|
||||
// TEST(FooTest, RunsCallbackWithBarArgument) {
|
||||
// MockFunction<int(string)> callback;
|
||||
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
|
||||
// Foo(callback.AsStdFunction());
|
||||
// }
|
||||
template <typename F>
|
||||
class MockFunction;
|
||||
|
||||
template <typename R, typename... Args>
|
||||
class MockFunction<R(Args...)> {
|
||||
public:
|
||||
MockFunction() {}
|
||||
MockFunction(const MockFunction&) = delete;
|
||||
MockFunction& operator=(const MockFunction&) = delete;
|
||||
|
||||
std::function<R(Args...)> AsStdFunction() {
|
||||
return [this](Args... args) -> R {
|
||||
return this->Call(std::forward<Args>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
// Implementation detail: the expansion of the MOCK_METHOD macro.
|
||||
R Call(Args... args) {
|
||||
mock_.SetOwnerAndName(this, "Call");
|
||||
return mock_.Invoke(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
|
||||
mock_.RegisterOwner(this);
|
||||
return mock_.With(std::move(m)...);
|
||||
}
|
||||
|
||||
internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
|
||||
R (*)(Args...)) {
|
||||
return this->gmock_Call(::testing::A<Args>()...);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable internal::FunctionMocker<R(Args...)> mock_;
|
||||
};
|
||||
|
||||
// The style guide prohibits "using" statements in a namespace scope
|
||||
// inside a header file. However, the MockSpec class template is
|
||||
// meant to be defined in the ::testing namespace. The following line
|
||||
|
Loading…
Reference in New Issue
Block a user