Skip to content

Commit 6386897

Browse files
jacobsacopybara-github
authored andcommitted
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
1 parent bda8544 commit 6386897

File tree

3 files changed

+59
-20
lines changed

3 files changed

+59
-20
lines changed

docs/gmock_cook_book.md

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3812,35 +3812,74 @@ Cardinality EvenNumber() {
38123812
.Times(EvenNumber());
38133813
```
38143814

3815-
### Writing New Actions Quickly {#QuickNewActions}
3815+
### Writing New Actions {#QuickNewActions}
38163816

38173817
If the built-in actions don't work for you, you can easily define your own one.
3818-
Just define a functor class with a (possibly templated) call operator, matching
3819-
the signature of your action.
3818+
All you need is a call operator with a signature compatible with the mocked
3819+
function. So you can use a lambda:
38203820

3821-
```cpp
3822-
struct Increment {
3823-
template <typename T>
3824-
T operator()(T* arg) {
3825-
return ++(*arg);
3826-
}
3827-
}
3821+
```
3822+
MockFunction<int(int)> mock;
3823+
EXPECT_CALL(mock, Call).WillOnce([](const int input) { return input * 7; });
3824+
EXPECT_EQ(14, mock.AsStdFunction()(2));
38283825
```
38293826

3830-
The same approach works with stateful functors (or any callable, really):
3827+
Or a struct with a call operator (even a templated one):
38313828

38323829
```
38333830
struct MultiplyBy {
38343831
template <typename T>
38353832
T operator()(T arg) { return arg * multiplier; }
38363833

38373834
int multiplier;
3838-
}
3835+
};
38393836

38403837
// Then use:
38413838
// EXPECT_CALL(...).WillOnce(MultiplyBy{7});
38423839
```
38433840

3841+
It's also fine for the callable to take no arguments, ignoring the arguments
3842+
supplied to the mock function:
3843+
3844+
```
3845+
MockFunction<int(int)> mock;
3846+
EXPECT_CALL(mock, Call).WillOnce([] { return 17; });
3847+
EXPECT_EQ(17, mock.AsStdFunction()(0));
3848+
```
3849+
3850+
When used with `WillOnce`, the callable can assume it will be called at most
3851+
once and is allowed to be a move-only type:
3852+
3853+
```
3854+
// An action that contains move-only types and has an &&-qualified operator,
3855+
// demanding in the type system that it be called at most once. This can be
3856+
// used with WillOnce, but the compiler will reject it if handed to
3857+
// WillRepeatedly.
3858+
struct MoveOnlyAction {
3859+
std::unique_ptr<int> move_only_state;
3860+
std::unique_ptr<int> operator()() && { return std::move(move_only_state); }
3861+
};
3862+
3863+
MockFunction<std::unique_ptr<int>()> mock;
3864+
EXPECT_CALL(mock, Call).WillOnce(MoveOnlyAction{std::make_unique<int>(17)});
3865+
EXPECT_THAT(mock.AsStdFunction()(), Pointee(Eq(17)));
3866+
```
3867+
3868+
More generally, to use with a mock function whose signature is `R(Args...)` the
3869+
object can be anything convertible to `OnceAction<R(Args...)>` or
3870+
`Action<R(Args...)`>. The difference between the two is that `OnceAction` has
3871+
weaker requirements (`Action` requires a copy-constructible input that can be
3872+
called repeatedly whereas `OnceAction` requires only move-constructible and
3873+
supports `&&`-qualified call operators), but can be used only with `WillOnce`.
3874+
`OnceAction` is typically relevant only when supporting move-only types or
3875+
actions that want a type-system guarantee that they will be called at most once.
3876+
3877+
Typically the `OnceAction` and `Action` templates need not be referenced
3878+
directly in your actions: a struct or class with a call operator is sufficient,
3879+
as in the examples above. But fancier polymorphic actions that need to know the
3880+
specific return type of the mock function can define templated conversion
3881+
operators to make that possible. See `gmock-actions.h` for examples.
3882+
38443883
#### Legacy macro-based Actions
38453884

38463885
Before C++11, the functor-based actions were not supported; the old way of

googlemock/include/gmock/gmock-actions.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,16 +322,18 @@ struct is_callable_r_impl<void_t<call_result_t<F, Args...>>, R, F, Args...>
322322
template <typename R, typename F, typename... Args>
323323
using is_callable_r = is_callable_r_impl<void, R, F, Args...>;
324324

325+
} // namespace internal
326+
325327
// Specialized for function types below.
326328
template <typename F>
327329
class OnceAction;
328330

329331
// An action that can only be used once.
330332
//
331-
// This is what is accepted by WillOnce, which doesn't require the underlying
332-
// action to be copy-constructible (only move-constructible), and promises to
333-
// invoke it as an rvalue reference. This allows the action to work with
334-
// move-only types like std::move_only_function in a type-safe manner.
333+
// This is accepted by WillOnce, which doesn't require the underlying action to
334+
// be copy-constructible (only move-constructible), and promises to invoke it as
335+
// an rvalue reference. This allows the action to work with move-only types like
336+
// std::move_only_function in a type-safe manner.
335337
//
336338
// For example:
337339
//
@@ -501,8 +503,6 @@ class OnceAction<Result(Args...)> final {
501503
std::function<Result(Args...)> function_;
502504
};
503505

504-
} // namespace internal
505-
506506
// When an unexpected function call is encountered, Google Mock will
507507
// let it return a default value if the user has specified one for its
508508
// return type, or if the return type has a built-in default value;
@@ -742,7 +742,7 @@ class Action<R(Args...)> {
742742

743743
// An action can be used as a OnceAction, since it's obviously safe to call it
744744
// once.
745-
operator internal::OnceAction<F>() const { // NOLINT
745+
operator OnceAction<F>() const { // NOLINT
746746
// Return a OnceAction-compatible callable that calls Perform with the
747747
// arguments it is provided. We could instead just return fun_, but then
748748
// we'd need to handle the IsDoDefault() case separately.

googlemock/test/gmock-actions_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,7 @@ TEST(MockMethodTest, ActionSwallowsAllArguments) {
19201920

19211921
struct ActionWithTemplatedConversionOperators {
19221922
template <typename... Args>
1923-
operator internal::OnceAction<int(Args...)>() && { // NOLINT
1923+
operator OnceAction<int(Args...)>() && { // NOLINT
19241924
return [] { return 17; };
19251925
}
19261926

0 commit comments

Comments
 (0)