mirror of
https://github.com/google/googletest.git
synced 2025-11-11 07:11:29 -05:00
Googletest export
Move FunctionMocker and MockFunction out of the pump file and implement with variadic templates. PiperOrigin-RevId: 220640265
This commit is contained in:
committed by
Gennadiy Civil
parent
105579a6e4
commit
de5be0eb28
@@ -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,10 +1158,9 @@ class TypedExpectation : public ExpectationBase {
|
||||
}
|
||||
|
||||
// Returns the action that should be taken for the current invocation.
|
||||
const Action<F>& GetCurrentAction(
|
||||
const FunctionMockerBase<F>* mocker,
|
||||
const ArgumentTuple& args) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,
|
||||
const ArgumentTuple& args) const
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
const int count = call_count();
|
||||
Assert(count >= 1, __FILE__, __LINE__,
|
||||
@@ -1199,12 +1195,11 @@ 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 ArgumentTuple& args,
|
||||
::std::ostream* what,
|
||||
::std::ostream* why)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,
|
||||
const ArgumentTuple& args,
|
||||
::std::ostream* what,
|
||||
::std::ostream* why)
|
||||
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
|
||||
g_gmock_mutex.AssertHeld();
|
||||
if (IsSaturated()) {
|
||||
// We have an excessive call.
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user