Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
59e65d08
Commit
59e65d08
authored
Mar 24, 2020
by
Xiaoyi Zhang
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2350 from adambadura:MockFunctionFromStdFunction
PiperOrigin-RevId: 302677275
parents
61629b49
53740ebc
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
143 additions
and
38 deletions
+143
-38
gmock-spec-builders.h
googlemock/include/gmock/gmock-spec-builders.h
+92
-38
gmock-function-mocker_test.cc
googlemock/test/gmock-function-mocker_test.cc
+51
-0
No files found.
googlemock/include/gmock/gmock-spec-builders.h
View file @
59e65d08
...
@@ -1786,10 +1786,79 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
...
@@ -1786,10 +1786,79 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
}
// namespace internal
}
// namespace internal
// A MockFunction<F> class has one mock method whose type is F. It is
namespace
internal
{
// 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
template
<
typename
F
>
// the right times). For example, if you are exercising code:
class
MockFunction
;
template
<
typename
R
,
typename
...
Args
>
class
MockFunction
<
R
(
Args
...)
>
{
public
:
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
)...);
}
MockSpec
<
R
(
Args
...)
>
gmock_Call
(
Matcher
<
Args
>
...
m
)
{
mock_
.
RegisterOwner
(
this
);
return
mock_
.
With
(
std
::
move
(
m
)...);
}
MockSpec
<
R
(
Args
...)
>
gmock_Call
(
const
WithoutMatchers
&
,
R
(
*
)(
Args
...))
{
return
this
->
gmock_Call
(
::
testing
::
A
<
Args
>
()...);
}
protected
:
MockFunction
()
=
default
;
~
MockFunction
()
=
default
;
private
:
FunctionMocker
<
R
(
Args
...)
>
mock_
;
};
/*
The SignatureOf<F> struct is a meta-function returning function signature
corresponding to the provided F argument.
It makes use of MockFunction easier by allowing it to accept more F arguments
than just function signatures.
Specializations provided here cover only a signature type itself and
std::function. However, if need be it can be easily extended to cover also other
types (like for example boost::function).
*/
template
<
typename
F
>
struct
SignatureOf
;
template
<
typename
R
,
typename
...
Args
>
struct
SignatureOf
<
R
(
Args
...)
>
{
using
type
=
R
(
Args
...);
};
template
<
typename
F
>
struct
SignatureOf
<
std
::
function
<
F
>>
:
SignatureOf
<
F
>
{};
template
<
typename
F
>
using
SignatureOfT
=
typename
SignatureOf
<
F
>::
type
;
}
// namespace internal
// A MockFunction<F> type has one mock method whose type is
// internal::SignatureOfT<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(1);
// Foo(2);
// Foo(2);
...
@@ -1823,49 +1892,34 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
...
@@ -1823,49 +1892,34 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
// Bar("a") is called by which call to Foo().
// Bar("a") is called by which call to Foo().
//
//
// MockFunction<F> can also be used to exercise code that accepts
// MockFunction<F> can also be used to exercise code that accepts
// std::function<
F> callbacks. To do so, use AsStdFunction() method
// std::function<
internal::SignatureOfT<F>> callbacks. To do so, use
//
to create std::function proxy forwarding to original object's Call.
//
AsStdFunction() method to create std::function proxy forwarding to
// Example:
//
original object's Call.
Example:
//
//
// TEST(FooTest, RunsCallbackWithBarArgument) {
// TEST(FooTest, RunsCallbackWithBarArgument) {
// MockFunction<int(string)> callback;
// MockFunction<int(string)> callback;
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
// Foo(callback.AsStdFunction());
// Foo(callback.AsStdFunction());
// }
// }
//
// The internal::SignatureOfT<F> indirection allows to use other types
// than just function signature type. This is typically useful when
// providing a mock for a predefined std::function type. Example:
//
// using FilterPredicate = std::function<bool(string)>;
// void MyFilterAlgorithm(FilterPredicate predicate);
//
// TEST(FooTest, FilterPredicateAlwaysAccepts) {
// MockFunction<FilterPredicate> predicateMock;
// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true));
// MyFilterAlgorithm(predicateMock.AsStdFunction());
// }
template
<
typename
F
>
template
<
typename
F
>
class
MockFunction
;
class
MockFunction
:
public
internal
::
MockFunction
<
internal
::
SignatureOfT
<
F
>>
{
using
Base
=
internal
::
MockFunction
<
internal
::
SignatureOfT
<
F
>>
;
template
<
typename
R
,
typename
...
Args
>
class
MockFunction
<
R
(
Args
...)
>
{
public
:
public
:
MockFunction
()
{}
using
Base
::
Base
;
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
:
internal
::
FunctionMocker
<
R
(
Args
...)
>
mock_
;
};
};
// The style guide prohibits "using" statements in a namespace scope
// The style guide prohibits "using" statements in a namespace scope
...
...
googlemock/test/gmock-function-mocker_test.cc
View file @
59e65d08
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
# include <objbase.h>
# include <objbase.h>
#endif // GTEST_OS_WINDOWS
#endif // GTEST_OS_WINDOWS
#include <functional>
#include <map>
#include <map>
#include <string>
#include <string>
#include <type_traits>
#include <type_traits>
...
@@ -778,6 +779,56 @@ TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
...
@@ -778,6 +779,56 @@ TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
EXPECT_EQ
(
-
1
,
call
(
foo
.
AsStdFunction
(),
i
));
EXPECT_EQ
(
-
1
,
call
(
foo
.
AsStdFunction
(),
i
));
}
}
namespace
{
template
<
typename
Expected
,
typename
F
>
static
constexpr
bool
IsMockFunctionTemplateArgumentDeducedTo
(
const
MockFunction
<
F
>&
)
{
return
std
::
is_same
<
F
,
Expected
>::
value
;
}
}
// namespace
template
<
typename
F
>
class
MockMethodMockFunctionSignatureTest
:
public
Test
{};
using
MockMethodMockFunctionSignatureTypes
=
Types
<
void
(),
int
(),
void
(
int
),
int
(
int
),
int
(
bool
,
int
),
int
(
bool
,
char
,
int
,
int
,
int
,
int
,
int
,
char
,
int
,
bool
)
>
;
TYPED_TEST_SUITE
(
MockMethodMockFunctionSignatureTest
,
MockMethodMockFunctionSignatureTypes
);
TYPED_TEST
(
MockMethodMockFunctionSignatureTest
,
IsMockFunctionTemplateArgumentDeducedForRawSignature
)
{
using
Argument
=
TypeParam
;
MockFunction
<
Argument
>
foo
;
EXPECT_TRUE
(
IsMockFunctionTemplateArgumentDeducedTo
<
Argument
>
(
foo
));
}
TYPED_TEST
(
MockMethodMockFunctionSignatureTest
,
IsMockFunctionTemplateArgumentDeducedForStdFunction
)
{
using
Argument
=
std
::
function
<
TypeParam
>
;
MockFunction
<
Argument
>
foo
;
EXPECT_TRUE
(
IsMockFunctionTemplateArgumentDeducedTo
<
Argument
>
(
foo
));
}
TYPED_TEST
(
MockMethodMockFunctionSignatureTest
,
IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction
)
{
using
ForRawSignature
=
decltype
(
&
MockFunction
<
TypeParam
>::
Call
);
using
ForStdFunction
=
decltype
(
&
MockFunction
<
std
::
function
<
TypeParam
>>::
Call
);
EXPECT_TRUE
((
std
::
is_same
<
ForRawSignature
,
ForStdFunction
>::
value
));
}
TYPED_TEST
(
MockMethodMockFunctionSignatureTest
,
IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction
)
{
using
ForRawSignature
=
decltype
(
&
MockFunction
<
TypeParam
>::
AsStdFunction
);
using
ForStdFunction
=
decltype
(
&
MockFunction
<
std
::
function
<
TypeParam
>>::
AsStdFunction
);
EXPECT_TRUE
((
std
::
is_same
<
ForRawSignature
,
ForStdFunction
>::
value
));
}
struct
MockMethodSizes0
{
struct
MockMethodSizes0
{
MOCK_METHOD
(
void
,
func
,
());
MOCK_METHOD
(
void
,
func
,
());
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment