"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "docs/gmock_cook_book.md" between
googletest-release-1.11.0.tar.gz and googletest-release-1.12.0.tar.gz

About: GoogleTest is Google's (unit) testing and mocking framework for C++ tests.

gmock_cook_book.md  (googletest-release-1.11.0):gmock_cook_book.md  (googletest-release-1.12.0)
skipping to change at line 395 skipping to change at line 395
<td>New</td> <td>New</td>
<td><code>MOCK_METHOD(bool, Foo, (int), (const, Calltype(STDMETHODCALLTYPE)) )</code></td> <td><code>MOCK_METHOD(bool, Foo, (int), (const, Calltype(STDMETHODCALLTYPE)) )</code></td>
</tr> </tr>
</table> </table>
### The Nice, the Strict, and the Naggy {#NiceStrictNaggy} ### The Nice, the Strict, and the Naggy {#NiceStrictNaggy}
If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an
"uninteresting call", and the default action (which can be specified using "uninteresting call", and the default action (which can be specified using
`ON_CALL()`) of the method will be taken. Currently, an uninteresting call will `ON_CALL()`) of the method will be taken. Currently, an uninteresting call will
also by default cause gMock to print a warning. (In the future, we might remove also by default cause gMock to print a warning.
this warning by default.)
However, sometimes you may want to ignore these uninteresting calls, and However, sometimes you may want to ignore these uninteresting calls, and
sometimes you may want to treat them as errors. gMock lets you make the decision sometimes you may want to treat them as errors. gMock lets you make the decision
on a per-mock-object basis. on a per-mock-object basis.
Suppose your test uses a mock class `MockFoo`: Suppose your test uses a mock class `MockFoo`:
```cpp ```cpp
TEST(...) { TEST(...) {
MockFoo mock_foo; MockFoo mock_foo;
skipping to change at line 1087 skipping to change at line 1086
using ::testing::_; using ::testing::_;
using ::testing::AllOf; using ::testing::AllOf;
using ::testing::Args; using ::testing::Args;
using ::testing::Lt; using ::testing::Lt;
... ...
EXPECT_CALL(foo, Blah) EXPECT_CALL(foo, Blah)
.With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt())));
``` ```
says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y < says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y <
z`. Note that in this example, it wasn't necessary specify the positional z`. Note that in this example, it wasn't necessary to specify the positional
matchers. matchers.
As a convenience and example, gMock provides some matchers for 2-tuples, As a convenience and example, gMock provides some matchers for 2-tuples,
including the `Lt()` matcher above. See including the `Lt()` matcher above. See
[Multi-argument Matchers](reference/matchers.md#MultiArgMatchers) for the [Multi-argument Matchers](reference/matchers.md#MultiArgMatchers) for the
complete list. complete list.
Note that if you want to pass the arguments to a predicate of your own (e.g. Note that if you want to pass the arguments to a predicate of your own (e.g.
`.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to `.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to
take a `std::tuple` as its argument; gMock will pass the `n` selected arguments take a `std::tuple` as its argument; gMock will pass the `n` selected arguments
skipping to change at line 1303 skipping to change at line 1302
without worrying that a `NULL` pointer will crash your test. without worrying that a `NULL` pointer will crash your test.
Also, did we tell you that `Pointee()` works with both raw pointers **and** Also, did we tell you that `Pointee()` works with both raw pointers **and**
smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)? smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)?
What if you have a pointer to pointer? You guessed it - you can use nested What if you have a pointer to pointer? You guessed it - you can use nested
`Pointee()` to probe deeper inside the value. For example, `Pointee()` to probe deeper inside the value. For example,
`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points `Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points
to a number less than 3 (what a mouthful...). to a number less than 3 (what a mouthful...).
### Testing a Certain Property of an Object ### Defining a Custom Matcher Class {#CustomMatcherClass}
Sometimes you want to specify that an object argument has a certain property, Most matchers can be simply defined using [the MATCHER* macros](#NewMatchers),
but there is no existing matcher that does this. If you want good error which are terse and flexible, and produce good error messages. However, these
messages, you should [define a matcher](#NewMatchers). If you want to do it macros are not very explicit about the interfaces they create and are not always
quick and dirty, you could get away with writing an ordinary function. suitable, especially for matchers that will be widely reused.
Let's say you have a mock function that takes an object of type `Foo`, which has For more advanced cases, you may need to define your own matcher class. A custom
an `int bar()` method and an `int baz()` method, and you want to constrain that matcher allows you to test a specific invariant property of that object. Let's
the argument's `bar()` value plus its `baz()` value is a given number. Here's take a look at how to do so.
how you can define a matcher to do it:
Imagine you have a mock function that takes an object of type `Foo`, which has
an `int bar()` method and an `int baz()` method. You want to constrain that the
argument's `bar()` value plus its `baz()` value is a given number. (This is an
invariant.) Here's how we can write and use a matcher class to do so:
```cpp ```cpp
using ::testing::Matcher;
class BarPlusBazEqMatcher { class BarPlusBazEqMatcher {
public: public:
using is_gtest_matcher = void;
explicit BarPlusBazEqMatcher(int expected_sum) explicit BarPlusBazEqMatcher(int expected_sum)
: expected_sum_(expected_sum) {} : expected_sum_(expected_sum) {}
bool MatchAndExplain(const Foo& foo, bool MatchAndExplain(const Foo& foo,
std::ostream* /* listener */) const { std::ostream* /* listener */) const {
return (foo.bar() + foo.baz()) == expected_sum_; return (foo.bar() + foo.baz()) == expected_sum_;
} }
void DescribeTo(std::ostream& os) const { void DescribeTo(std::ostream* os) const {
os << "bar() + baz() equals " << expected_sum_; *os << "bar() + baz() equals " << expected_sum_;
} }
void DescribeNegationTo(std::ostream& os) const { void DescribeNegationTo(std::ostream* os) const {
os << "bar() + baz() does not equal " << expected_sum_; *os << "bar() + baz() does not equal " << expected_sum_;
} }
private: private:
const int expected_sum_; const int expected_sum_;
}; };
Matcher<const Foo&> BarPlusBazEq(int expected_sum) { ::testing::Matcher<const Foo&> BarPlusBazEq(int expected_sum) {
return BarPlusBazEqMatcher(expected_sum); return BarPlusBazEqMatcher(expected_sum);
} }
... ...
EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; Foo foo;
EXPECT_CALL(foo, BarPlusBazEq(5))...;
``` ```
### Matching Containers ### Matching Containers
Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock
function and you may want to validate it. Since most STL containers support the function and you may want to validate it. Since most STL containers support the
`==` operator, you can write `Eq(expected_container)` or simply `==` operator, you can write `Eq(expected_container)` or simply
`expected_container` to match a container exactly. `expected_container` to match a container exactly.
Sometimes, though, you may want to be more flexible (for example, the first Sometimes, though, you may want to be more flexible (for example, the first
skipping to change at line 1455 skipping to change at line 1459
should use `WhenSorted` around `ElementsAre`. should use `WhenSorted` around `ElementsAre`.
### Sharing Matchers ### Sharing Matchers
Under the hood, a gMock matcher object consists of a pointer to a ref-counted Under the hood, a gMock matcher object consists of a pointer to a ref-counted
implementation object. Copying matchers is allowed and very efficient, as only implementation object. Copying matchers is allowed and very efficient, as only
the pointer is copied. When the last matcher that references the implementation the pointer is copied. When the last matcher that references the implementation
object dies, the implementation object will be deleted. object dies, the implementation object will be deleted.
Therefore, if you have some complex matcher that you want to use again and Therefore, if you have some complex matcher that you want to use again and
again, there is no need to build it everytime. Just assign it to a matcher again, there is no need to build it every time. Just assign it to a matcher
variable and use that variable repeatedly! For example, variable and use that variable repeatedly! For example,
```cpp ```cpp
using ::testing::AllOf; using ::testing::AllOf;
using ::testing::Gt; using ::testing::Gt;
using ::testing::Le; using ::testing::Le;
using ::testing::Matcher; using ::testing::Matcher;
... ...
Matcher<int> in_range = AllOf(Gt(5), Le(10)); Matcher<int> in_range = AllOf(Gt(5), Le(10));
... use in_range as a matcher in multiple EXPECT_CALLs ... ... use in_range as a matcher in multiple EXPECT_CALLs ...
skipping to change at line 1757 skipping to change at line 1761
.InSequence(s2); .InSequence(s2);
``` ```
specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`): specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`):
```text ```text
+---> B +---> B
| |
A ---| A ---|
| |
+---> C ---> D +---> C ---> D
``` ```
This means that A must occur before B and C, and C must occur before D. There's This means that A must occur before B and C, and C must occur before D. There's
no restriction about the order other than these. no restriction about the order other than these.
### Controlling When an Expectation Retires ### Controlling When an Expectation Retires
When a mock method is called, gMock only considers expectations that are still When a mock method is called, gMock only considers expectations that are still
active. An expectation is active when created, and becomes inactive (aka active. An expectation is active when created, and becomes inactive (aka
*retires*) when a call that has to occur later has occurred. For example, in *retires*) when a call that has to occur later has occurred. For example, in
skipping to change at line 1983 skipping to change at line 1987
`SetArgPointee()` conveniently makes an internal copy of the value you pass to `SetArgPointee()` conveniently makes an internal copy of the value you pass to
it, removing the need to keep the value in scope and alive. The implication it, removing the need to keep the value in scope and alive. The implication
however is that the value must have a copy constructor and assignment operator. however is that the value must have a copy constructor and assignment operator.
If the mock method also needs to return a value as well, you can chain If the mock method also needs to return a value as well, you can chain
`SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the `SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the
`Return()` statement last: `Return()` statement last:
```cpp ```cpp
using ::testing::_; using ::testing::_;
using ::testing::DoAll;
using ::testing::Return; using ::testing::Return;
using ::testing::SetArgPointee; using ::testing::SetArgPointee;
class MockMutator : public Mutator { class MockMutator : public Mutator {
public: public:
... ...
MOCK_METHOD(bool, MutateInt, (int* value), (override)); MOCK_METHOD(bool, MutateInt, (int* value), (override));
} }
... ...
MockMutator mutator; MockMutator mutator;
skipping to change at line 2036 skipping to change at line 2041
using ::testing::SetArrayArgument; using ::testing::SetArrayArgument;
class MockRolodex : public Rolodex { class MockRolodex : public Rolodex {
public: public:
MOCK_METHOD(void, GetNames, (std::back_insert_iterator<vector<string>>), MOCK_METHOD(void, GetNames, (std::back_insert_iterator<vector<string>>),
(override)); (override));
... ...
} }
... ...
MockRolodex rolodex; MockRolodex rolodex;
vector<string> names; vector<string> names = {"George", "John", "Thomas"};
names.push_back("George");
names.push_back("John");
names.push_back("Thomas");
EXPECT_CALL(rolodex, GetNames(_)) EXPECT_CALL(rolodex, GetNames(_))
.WillOnce(SetArrayArgument<0>(names.begin(), names.end())); .WillOnce(SetArrayArgument<0>(names.begin(), names.end()));
``` ```
### Changing a Mock Object's Behavior Based on the State ### Changing a Mock Object's Behavior Based on the State
If you expect a call to change the behavior of a mock object, you can use If you expect a call to change the behavior of a mock object, you can use
`::testing::InSequence` to specify different behaviors before and after the `::testing::InSequence` to specify different behaviors before and after the
call: call:
skipping to change at line 2606 skipping to change at line 2608
``` ```
### Sharing Actions ### Sharing Actions
Just like matchers, a gMock action object consists of a pointer to a ref-counted Just like matchers, a gMock action object consists of a pointer to a ref-counted
implementation object. Therefore copying actions is also allowed and very implementation object. Therefore copying actions is also allowed and very
efficient. When the last action that references the implementation object dies, efficient. When the last action that references the implementation object dies,
the implementation object will be deleted. the implementation object will be deleted.
If you have some complex action that you want to use again and again, you may If you have some complex action that you want to use again and again, you may
not have to build it from scratch everytime. If the action doesn't have an not have to build it from scratch every time. If the action doesn't have an
internal state (i.e. if it always does the same thing no matter how many times internal state (i.e. if it always does the same thing no matter how many times
it has been called), you can assign it to an action variable and use that it has been called), you can assign it to an action variable and use that
variable repeatedly. For example: variable repeatedly. For example:
```cpp ```cpp
using ::testing::Action; using ::testing::Action;
using ::testing::DoAll; using ::testing::DoAll;
using ::testing::Return; using ::testing::Return;
using ::testing::SetArgPointee; using ::testing::SetArgPointee;
... ...
skipping to change at line 3811 skipping to change at line 3813
Cardinality EvenNumber() { Cardinality EvenNumber() {
return MakeCardinality(new EvenNumberCardinality); return MakeCardinality(new EvenNumberCardinality);
} }
... ...
EXPECT_CALL(foo, Bar(3)) EXPECT_CALL(foo, Bar(3))
.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 {
template <typename T> template <typename T>
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
writing actions was through a set of `ACTION*` macros. We suggest to avoid them writing actions was through a set of `ACTION*` macros. We suggest to avoid them
in new code; they hide a lot of logic behind the macro, potentially leading to in new code; they hide a lot of logic behind the macro, potentially leading to
harder-to-understand compiler errors. Nevertheless, we cover them here for harder-to-understand compiler errors. Nevertheless, we cover them here for
completeness. completeness.
By writing By writing
skipping to change at line 4191 skipping to change at line 4232
// To get the i-th (0-based) argument, use std::get(args). // To get the i-th (0-based) argument, use std::get(args).
return std::get<1>(args); return std::get<1>(args);
} }
}; };
``` ```
This implementation class does *not* need to inherit from any particular class. This implementation class does *not* need to inherit from any particular class.
What matters is that it must have a `Perform()` method template. This method What matters is that it must have a `Perform()` method template. This method
template takes the mock function's arguments as a tuple in a **single** template takes the mock function's arguments as a tuple in a **single**
argument, and returns the result of the action. It can be either `const` or not, argument, and returns the result of the action. It can be either `const` or not,
but must be invokable with exactly one template argument, which is the result but must be invocable with exactly one template argument, which is the result
type. In other words, you must be able to call `Perform<R>(args)` where `R` is type. In other words, you must be able to call `Perform<R>(args)` where `R` is
the mock function's return type and `args` is its arguments in a tuple. the mock function's return type and `args` is its arguments in a tuple.
Next, we use `MakePolymorphicAction()` to turn an instance of the implementation Next, we use `MakePolymorphicAction()` to turn an instance of the implementation
class into the polymorphic action we need. It will be convenient to have a class into the polymorphic action we need. It will be convenient to have a
wrapper for this: wrapper for this:
```cpp ```cpp
using ::testing::MakePolymorphicAction; using ::testing::MakePolymorphicAction;
using ::testing::PolymorphicAction; using ::testing::PolymorphicAction;
 End of changes. 22 change blocks. 
41 lines changed or deleted 82 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)