gmock-actions: make OnceAction public.
So that it can be referenced in conversion operators for actions that need to know the concrete return type. PiperOrigin-RevId: 447889344 Change-Id: I643d3298bc8effd08741282a956c221f9d67d378
This commit is contained in:
parent
bda85449f4
commit
6386897feb
@ -3812,22 +3812,19 @@ Cardinality EvenNumber() {
|
|||||||
.Times(EvenNumber());
|
.Times(EvenNumber());
|
||||||
```
|
```
|
||||||
|
|
||||||
### Writing New Actions Quickly {#QuickNewActions}
|
### Writing New Actions {#QuickNewActions}
|
||||||
|
|
||||||
If the built-in actions don't work for you, you can easily define your own one.
|
If the built-in actions don't work for you, you can easily define your own one.
|
||||||
Just define a functor class with a (possibly templated) call operator, matching
|
All you need is a call operator with a signature compatible with the mocked
|
||||||
the signature of your action.
|
function. So you can use a lambda:
|
||||||
|
|
||||||
```cpp
|
```
|
||||||
struct Increment {
|
MockFunction<int(int)> mock;
|
||||||
template <typename T>
|
EXPECT_CALL(mock, Call).WillOnce([](const int input) { return input * 7; });
|
||||||
T operator()(T* arg) {
|
EXPECT_EQ(14, mock.AsStdFunction()(2));
|
||||||
return ++(*arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The same approach works with stateful functors (or any callable, really):
|
Or a struct with a call operator (even a templated one):
|
||||||
|
|
||||||
```
|
```
|
||||||
struct MultiplyBy {
|
struct MultiplyBy {
|
||||||
@ -3835,12 +3832,54 @@ struct MultiplyBy {
|
|||||||
T operator()(T arg) { return arg * multiplier; }
|
T operator()(T arg) { return arg * multiplier; }
|
||||||
|
|
||||||
int multiplier;
|
int multiplier;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Then use:
|
// Then use:
|
||||||
// EXPECT_CALL(...).WillOnce(MultiplyBy{7});
|
// EXPECT_CALL(...).WillOnce(MultiplyBy{7});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It's also fine for the callable to take no arguments, ignoring the arguments
|
||||||
|
supplied to the mock function:
|
||||||
|
|
||||||
|
```
|
||||||
|
MockFunction<int(int)> mock;
|
||||||
|
EXPECT_CALL(mock, Call).WillOnce([] { return 17; });
|
||||||
|
EXPECT_EQ(17, mock.AsStdFunction()(0));
|
||||||
|
```
|
||||||
|
|
||||||
|
When used with `WillOnce`, the callable can assume it will be called at most
|
||||||
|
once and is allowed to be a move-only type:
|
||||||
|
|
||||||
|
```
|
||||||
|
// An action that contains move-only types and has an &&-qualified operator,
|
||||||
|
// demanding in the type system that it be called at most once. This can be
|
||||||
|
// used with WillOnce, but the compiler will reject it if handed to
|
||||||
|
// WillRepeatedly.
|
||||||
|
struct MoveOnlyAction {
|
||||||
|
std::unique_ptr<int> move_only_state;
|
||||||
|
std::unique_ptr<int> operator()() && { return std::move(move_only_state); }
|
||||||
|
};
|
||||||
|
|
||||||
|
MockFunction<std::unique_ptr<int>()> mock;
|
||||||
|
EXPECT_CALL(mock, Call).WillOnce(MoveOnlyAction{std::make_unique<int>(17)});
|
||||||
|
EXPECT_THAT(mock.AsStdFunction()(), Pointee(Eq(17)));
|
||||||
|
```
|
||||||
|
|
||||||
|
More generally, to use with a mock function whose signature is `R(Args...)` the
|
||||||
|
object can be anything convertible to `OnceAction<R(Args...)>` or
|
||||||
|
`Action<R(Args...)`>. The difference between the two is that `OnceAction` has
|
||||||
|
weaker requirements (`Action` requires a copy-constructible input that can be
|
||||||
|
called repeatedly whereas `OnceAction` requires only move-constructible and
|
||||||
|
supports `&&`-qualified call operators), but can be used only with `WillOnce`.
|
||||||
|
`OnceAction` is typically relevant only when supporting move-only types or
|
||||||
|
actions that want a type-system guarantee that they will be called at most once.
|
||||||
|
|
||||||
|
Typically the `OnceAction` and `Action` templates need not be referenced
|
||||||
|
directly in your actions: a struct or class with a call operator is sufficient,
|
||||||
|
as in the examples above. But fancier polymorphic actions that need to know the
|
||||||
|
specific return type of the mock function can define templated conversion
|
||||||
|
operators to make that possible. See `gmock-actions.h` for examples.
|
||||||
|
|
||||||
#### Legacy macro-based Actions
|
#### Legacy macro-based Actions
|
||||||
|
|
||||||
Before C++11, the functor-based actions were not supported; the old way of
|
Before C++11, the functor-based actions were not supported; the old way of
|
||||||
|
@ -322,16 +322,18 @@ struct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>
|
|||||||
template <typename R, typename F, typename... Args>
|
template <typename R, typename F, typename... Args>
|
||||||
using is_callable_r = is_callable_r_impl<void, R, F, Args...>;
|
using is_callable_r = is_callable_r_impl<void, R, F, Args...>;
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
// Specialized for function types below.
|
// Specialized for function types below.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
class OnceAction;
|
class OnceAction;
|
||||||
|
|
||||||
// An action that can only be used once.
|
// An action that can only be used once.
|
||||||
//
|
//
|
||||||
// This is what is accepted by WillOnce, which doesn't require the underlying
|
// This is accepted by WillOnce, which doesn't require the underlying action to
|
||||||
// action to be copy-constructible (only move-constructible), and promises to
|
// be copy-constructible (only move-constructible), and promises to invoke it as
|
||||||
// invoke it as an rvalue reference. This allows the action to work with
|
// an rvalue reference. This allows the action to work with move-only types like
|
||||||
// move-only types like std::move_only_function in a type-safe manner.
|
// std::move_only_function in a type-safe manner.
|
||||||
//
|
//
|
||||||
// For example:
|
// For example:
|
||||||
//
|
//
|
||||||
@ -501,8 +503,6 @@ class OnceAction<Result(Args...)> final {
|
|||||||
std::function<Result(Args...)> function_;
|
std::function<Result(Args...)> function_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
// When an unexpected function call is encountered, Google Mock will
|
// When an unexpected function call is encountered, Google Mock will
|
||||||
// let it return a default value if the user has specified one for its
|
// let it return a default value if the user has specified one for its
|
||||||
// return type, or if the return type has a built-in default value;
|
// return type, or if the return type has a built-in default value;
|
||||||
@ -742,7 +742,7 @@ class Action<R(Args...)> {
|
|||||||
|
|
||||||
// An action can be used as a OnceAction, since it's obviously safe to call it
|
// An action can be used as a OnceAction, since it's obviously safe to call it
|
||||||
// once.
|
// once.
|
||||||
operator internal::OnceAction<F>() const { // NOLINT
|
operator OnceAction<F>() const { // NOLINT
|
||||||
// Return a OnceAction-compatible callable that calls Perform with the
|
// Return a OnceAction-compatible callable that calls Perform with the
|
||||||
// arguments it is provided. We could instead just return fun_, but then
|
// arguments it is provided. We could instead just return fun_, but then
|
||||||
// we'd need to handle the IsDoDefault() case separately.
|
// we'd need to handle the IsDoDefault() case separately.
|
||||||
|
@ -1920,7 +1920,7 @@ TEST(MockMethodTest, ActionSwallowsAllArguments) {
|
|||||||
|
|
||||||
struct ActionWithTemplatedConversionOperators {
|
struct ActionWithTemplatedConversionOperators {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
operator internal::OnceAction<int(Args...)>() && { // NOLINT
|
operator OnceAction<int(Args...)>() && { // NOLINT
|
||||||
return [] { return 17; };
|
return [] { return 17; };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user