# gMock Cookbook

You can find recipes for using gMock here. If you haven't yet, please read
[the dummy guide](gmock_for_dummies.md) first to make sure you understand the
basics.

{: .callout .note}
**Note:** gMock lives in the `testing` name space. For readability, it is
recommended to write `using ::testing::Foo;` once in your file before using the
name `Foo` defined by gMock. We omit such `using` statements in this section for
brevity, but you should do it in your own code.

## Creating Mock Classes

Mock classes are defined as normal classes, using the `MOCK_METHOD` macro to
generate mocked methods. The macro gets 3 or 4 parameters:

```cpp
class MyMock {
 public:
  MOCK_METHOD(ReturnType, MethodName, (Args...));
  MOCK_METHOD(ReturnType, MethodName, (Args...), (Specs...));
};
```

The first 3 parameters are simply the method declaration, split into 3 parts.
The 4th parameter accepts a closed list of qualifiers, which affect the
generated method:

*   **`const`** - Makes the mocked method a `const` method. Required if
    overriding a `const` method.
*   **`override`** - Marks the method with `override`. Recommended if overriding
    a `virtual` method.
*   **`noexcept`** - Marks the method with `noexcept`. Required if overriding a
    `noexcept` method.
*   **`Calltype(...)`** - Sets the call type for the method (e.g. to
    `STDMETHODCALLTYPE`), useful in Windows.
*   **`ref(...)`** - Marks the method with the reference qualification
    specified. Required if overriding a method that has reference
    qualifications. Eg `ref(&)` or `ref(&&)`.

### Dealing with unprotected commas

Unprotected commas, i.e. commas which are not surrounded by parentheses, prevent
`MOCK_METHOD` from parsing its arguments correctly:

{: .bad}
```cpp
class MockFoo {
 public:
  MOCK_METHOD(std::pair<bool, int>, GetPair, ());  // Won't compile!
  MOCK_METHOD(bool, CheckMap, (std::map<int, double>, bool));  // Won't compile!
};
```

Solution 1 - wrap with parentheses:

{: .good}
```cpp
class MockFoo {
 public:
  MOCK_METHOD((std::pair<bool, int>), GetPair, ());
  MOCK_METHOD(bool, CheckMap, ((std::map<int, double>), bool));
};
```

Note that wrapping a return or argument type with parentheses is, in general,
invalid C++. `MOCK_METHOD` removes the parentheses.

Solution 2 - define an alias:

{: .good}
```cpp
class MockFoo {
 public:
  using BoolAndInt = std::pair<bool, int>;
  MOCK_METHOD(BoolAndInt, GetPair, ());
  using MapIntDouble = std::map<int, double>;
  MOCK_METHOD(bool, CheckMap, (MapIntDouble, bool));
};
```

### Mocking Private or Protected Methods

You must always put a mock method definition (`MOCK_METHOD`) in a `public:`
section of the mock class, regardless of the method being mocked being `public`,
`protected`, or `private` in the base class. This allows `ON_CALL` and
`EXPECT_CALL` to reference the mock function from outside of the mock class.
(Yes, C++ allows a subclass to change the access level of a virtual function in
the base class.) Example:

```cpp
class Foo {
 public:
  ...
  virtual bool Transform(Gadget* g) = 0;

 protected:
  virtual void Resume();

 private:
  virtual int GetTimeOut();
};

class MockFoo : public Foo {
 public:
  ...
  MOCK_METHOD(bool, Transform, (Gadget* g), (override));

  // The following must be in the public section, even though the
  // methods are protected or private in the base class.
  MOCK_METHOD(void, Resume, (), (override));
  MOCK_METHOD(int, GetTimeOut, (), (override));
};
```

### Mocking Overloaded Methods

You can mock overloaded functions as usual. No special attention is required:

```cpp
class Foo {
  ...

  // Must be virtual as we'll inherit from Foo.
  virtual ~Foo();

  // Overloaded on the types and/or numbers of arguments.
  virtual int Add(Element x);
  virtual int Add(int times, Element x);

  // Overloaded on the const-ness of this object.
  virtual Bar& GetBar();
  virtual const Bar& GetBar() const;
};

class MockFoo : public Foo {
  ...
  MOCK_METHOD(int, Add, (Element x), (override));
  MOCK_METHOD(int, Add, (int times, Element x), (override));

  MOCK_METHOD(Bar&, GetBar, (), (override));
  MOCK_METHOD(const Bar&, GetBar, (), (const, override));
};
```

{: .callout .note}
**Note:** if you don't mock all versions of the overloaded method, the compiler
will give you a warning about some methods in the base class being hidden. To
fix that, use `using` to bring them in scope:

```cpp
class MockFoo : public Foo {
  ...
  using Foo::Add;
  MOCK_METHOD(int, Add, (Element x), (override));
  // We don't want to mock int Add(int times, Element x);
  ...
};
```

### Mocking Class Templates

You can mock class templates just like any class.

```cpp
template <typename Elem>
class StackInterface {
  ...
  // Must be virtual as we'll inherit from StackInterface.
  virtual ~StackInterface();

  virtual int GetSize() const = 0;
  virtual void Push(const Elem& x) = 0;
};

template <typename Elem>
class MockStack : public StackInterface<Elem> {
  ...
  MOCK_METHOD(int, GetSize, (), (override));
  MOCK_METHOD(void, Push, (const Elem& x), (override));
};
```

### Mocking Non-virtual Methods {#MockingNonVirtualMethods}

gMock can mock non-virtual functions to be used in Hi-perf dependency injection.

In this case, instead of sharing a common base class with the real class, your
mock class will be *unrelated* to the real class, but contain methods with the
same signatures. The syntax for mocking non-virtual methods is the *same* as
mocking virtual methods (just don't add `override`):

```cpp
// A simple packet stream class.  None of its members is virtual.
class ConcretePacketStream {
 public:
  void AppendPacket(Packet* new_packet);
  const Packet* GetPacket(size_t packet_number) const;
  size_t NumberOfPackets() const;
  ...
};

// A mock packet stream class.  It inherits from no other, but defines
// GetPacket() and NumberOfPackets().
class MockPacketStream {
 public:
  MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const));
  MOCK_METHOD(size_t, NumberOfPackets, (), (const));
  ...
};
```

Note that the mock class doesn't define `AppendPacket()`, unlike the real class.
That's fine as long as the test doesn't need to call it.

Next, you need a way to say that you want to use `ConcretePacketStream` in
production code, and use `MockPacketStream` in tests. Since the functions are
not virtual and the two classes are unrelated, you must specify your choice at
*compile time* (as opposed to run time).

One way to do it is to templatize your code that needs to use a packet stream.
More specifically, you will give your code a template type argument for the type
of the packet stream. In production, you will instantiate your template with
`ConcretePacketStream` as the type argument. In tests, you will instantiate the
same template with `MockPacketStream`. For example, you may write:

```cpp
template <class PacketStream>
void CreateConnection(PacketStream* stream) { ... }

template <class PacketStream>
class PacketReader {
 public:
  void ReadPackets(PacketStream* stream, size_t packet_num);
};
```

Then you can use `CreateConnection<ConcretePacketStream>()` and
`PacketReader<ConcretePacketStream>` in production code, and use
`CreateConnection<MockPacketStream>()` and `PacketReader<MockPacketStream>` in
tests.

```cpp
  MockPacketStream mock_stream;
  EXPECT_CALL(mock_stream, ...)...;
  .. set more expectations on mock_stream ...
  PacketReader<MockPacketStream> reader(&mock_stream);
  ... exercise reader ...
```

### Mocking Free Functions

It is not possible to directly mock a free function (i.e. a C-style function or
a static method). If you need to, you can rewrite your code to use an interface
(abstract class).

Instead of calling a free function (say, `OpenFile`) directly, introduce an
interface for it and have a concrete subclass that calls the free function:

```cpp
class FileInterface {
 public:
  ...
  virtual bool Open(const char* path, const char* mode) = 0;
};

class File : public FileInterface {
 public:
  ...
  bool Open(const char* path, const char* mode) override {
     return OpenFile(path, mode);
  }
};
```

Your code should talk to `FileInterface` to open a file. Now it's easy to mock
out the function.

This may seem like a lot of hassle, but in practice you often have multiple
related functions that you can put in the same interface, so the per-function
syntactic overhead will be much lower.

If you are concerned about the performance overhead incurred by virtual
functions, and profiling confirms your concern, you can combine this with the
recipe for [mocking non-virtual methods](#MockingNonVirtualMethods).

Alternatively, instead of introducing a new interface, you can rewrite your code
to accept a std::function instead of the free function, and then use
[MockFunction](#MockFunction) to mock the std::function.

### Old-Style `MOCK_METHODn` Macros

Before the generic `MOCK_METHOD` macro
[was introduced in 2018](https://github.com/google/googletest/commit/c5f08bf91944ce1b19bcf414fa1760e69d20afc2),
mocks where created using a family of macros collectively called `MOCK_METHODn`.
These macros are still supported, though migration to the new `MOCK_METHOD` is
recommended.

The macros in the `MOCK_METHODn` family differ from `MOCK_METHOD`:

*   The general structure is `MOCK_METHODn(MethodName, ReturnType(Args))`,
    instead of `MOCK_METHOD(ReturnType, MethodName, (Args))`.
*   The number `n` must equal the number of arguments.
*   When mocking a const method, one must use `MOCK_CONST_METHODn`.
*   When mocking a class template, the macro name must be suffixed with `_T`.
*   In order to specify the call type, the macro name must be suffixed with
    `_WITH_CALLTYPE`, and the call type is the first macro argument.

Old macros and their new equivalents:

<table>
  <tr><th colspan=2>Simple</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_METHOD1(Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int))</code></td>
  </tr>

  <tr><th colspan=2>Const Method</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_CONST_METHOD1(Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int), (const))</code></td>
  </tr>

  <tr><th colspan=2>Method in a Class Template</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_METHOD1_T(Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int))</code></td>
  </tr>

  <tr><th colspan=2>Const Method in a Class Template</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_CONST_METHOD1_T(Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int), (const))</code></td>
  </tr>

  <tr><th colspan=2>Method with Call Type</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int), (Calltype(STDMETHODCALLTYPE)))</code></td>
  </tr>

  <tr><th colspan=2>Const Method with Call Type</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int), (const, Calltype(STDMETHODCALLTYPE)))</code></td>
  </tr>

  <tr><th colspan=2>Method with Call Type in a Class Template</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int), (Calltype(STDMETHODCALLTYPE)))</code></td>
  </tr>

  <tr><th colspan=2>Const Method with Call Type in a Class Template</th></tr>
  <tr>
    <td>Old</td>
    <td><code>MOCK_CONST_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))</code></td>
  </tr>
  <tr>
    <td>New</td>
    <td><code>MOCK_METHOD(bool, Foo, (int), (const, Calltype(STDMETHODCALLTYPE)))</code></td>
  </tr>
</table>

### 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
"uninteresting call", and the default action (which can be specified using
`ON_CALL()`) of the method will be taken. Currently, an uninteresting call will
also by default cause gMock to print a warning.

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
on a per-mock-object basis.

Suppose your test uses a mock class `MockFoo`:

```cpp
TEST(...) {
  MockFoo mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}
```

If a method of `mock_foo` other than `DoThis()` is called, you will get a
warning. However, if you rewrite your test to use `NiceMock<MockFoo>` instead,
you can suppress the warning:

```cpp
using ::testing::NiceMock;

TEST(...) {
  NiceMock<MockFoo> mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}
```

`NiceMock<MockFoo>` is a subclass of `MockFoo`, so it can be used wherever
`MockFoo` is accepted.

It also works if `MockFoo`'s constructor takes some arguments, as
`NiceMock<MockFoo>` "inherits" `MockFoo`'s constructors:

```cpp
using ::testing::NiceMock;

TEST(...) {
  NiceMock<MockFoo> mock_foo(5, "hi");  // Calls MockFoo(5, "hi").
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}
```

The usage of `StrictMock` is similar, except that it makes all uninteresting
calls failures:

```cpp
using ::testing::StrictMock;

TEST(...) {
  StrictMock<MockFoo> mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...

  // The test will fail if a method of mock_foo other than DoThis()
  // is called.
}
```

{: .callout .note}
NOTE: `NiceMock` and `StrictMock` only affects *uninteresting* calls (calls of
*methods* with no expectations); they do not affect *unexpected* calls (calls of
methods with expectations, but they don't match). See
[Understanding Uninteresting vs Unexpected Calls](#uninteresting-vs-unexpected).

There are some caveats though (sadly they are side effects of C++'s
limitations):

1.  `NiceMock<MockFoo>` and `StrictMock<MockFoo>` only work for mock methods
    defined using the `MOCK_METHOD` macro **directly** in the `MockFoo` class.
    If a mock method is defined in a **base class** of `MockFoo`, the "nice" or
    "strict" modifier may not affect it, depending on the compiler. In
    particular, nesting `NiceMock` and `StrictMock` (e.g.
    `NiceMock<StrictMock<MockFoo> >`) is **not** supported.
2.  `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the
    destructor of `MockFoo` is not virtual. We would like to fix this, but it
    requires cleaning up existing tests.

Finally, you should be **very cautious** about when to use naggy or strict
mocks, as they tend to make tests more brittle and harder to maintain. When you
refactor your code without changing its externally visible behavior, ideally you
shouldn't need to update any tests. If your code interacts with a naggy mock,
however, you may start to get spammed with warnings as the result of your
change. Worse, if your code interacts with a strict mock, your tests may start
to fail and you'll be forced to fix them. Our general recommendation is to use
nice mocks (not yet the default) most of the time, use naggy mocks (the current
default) when developing or debugging tests, and use strict mocks only as the
last resort.

### Simplifying the Interface without Breaking Existing Code {#SimplerInterfaces}

Sometimes a method has a long list of arguments that is mostly uninteresting.
For example:

```cpp
class LogSink {
 public:
  ...
  virtual void send(LogSeverity severity, const char* full_filename,
                    const char* base_filename, int line,
                    const struct tm* tm_time,
                    const char* message, size_t message_len) = 0;
};
```

This method's argument list is lengthy and hard to work with (the `message`
argument is not even 0-terminated). If we mock it as is, using the mock will be
awkward. If, however, we try to simplify this interface, we'll need to fix all
clients depending on it, which is often infeasible.

The trick is to redispatch the method in the mock class:

```cpp
class ScopedMockLog : public LogSink {
 public:
  ...
  void send(LogSeverity severity, const char* full_filename,
                    const char* base_filename, int line, const tm* tm_time,
                    const char* message, size_t message_len) override {
    // We are only interested in the log severity, full file name, and
    // log message.
    Log(severity, full_filename, std::string(message, message_len));
  }

  // Implements the mock method:
  //
  //   void Log(LogSeverity severity,
  //            const string& file_path,
  //            const string& message);
  MOCK_METHOD(void, Log,
              (LogSeverity severity, const string& file_path,
               const string& message));
};
```

By defining a new mock method with a trimmed argument list, we make the mock
class more user-friendly.

This technique may also be applied to make overloaded methods more amenable to
mocking. For example, when overloads have been used to implement default
arguments:

```cpp
class MockTurtleFactory : public TurtleFactory {
 public:
  Turtle* MakeTurtle(int length, int weight) override { ... }
  Turtle* MakeTurtle(int length, int weight, int speed) override { ... }

  // the above methods delegate to this one:
  MOCK_METHOD(Turtle*, DoMakeTurtle, ());
};
```

This allows tests that don't care which overload was invoked to avoid specifying
argument matchers:

```cpp
ON_CALL(factory, DoMakeTurtle)
    .WillByDefault(Return(MakeMockTurtle()));
```

### Alternative to Mocking Concrete Classes

Often you may find yourself using classes that don't implement interfaces. In
order to test your code that uses such a class (let's call it `Concrete`), you
may be tempted to make the methods of `Concrete` virtual and then mock it.

Try not to do that.

Making a non-virtual function virtual is a big decision. It creates an extension
point where subclasses can tweak your class' behavior. This weakens your control
on the class because now it's harder to maintain the class invariants. You
should make a function virtual only when there is a valid reason for a subclass
to override it.

Mocking concrete classes directly is problematic as it creates a tight coupling
between the class and the tests - any small change in the class may invalidate
your tests and make test maintenance a pain.

To avoid such problems, many programmers have been practicing "coding to
interfaces": instead of talking to the `Concrete` class, your code would define
an interface and talk to it. Then you implement that interface as an adaptor on
top of `Concrete`. In tests, you can easily mock that interface to observe how
your code is doing.

This technique incurs some overhead:

*   You pay the cost of virtual function calls (usually not a problem).
*   There is more abstraction for the programmers to learn.

However, it can also bring significant benefits in addition to better
testability:

*   `Concrete`'s API may not fit your problem domain very well, as you may not
    be the only client it tries to serve. By designing your own interface, you
    have a chance to tailor it to your need - you may add higher-level
    functionalities, rename stuff, etc instead of just trimming the class. This
    allows you to write your code (user of the interface) in a more natural way,
    which means it will be more readable, more maintainable, and you'll be more
    productive.
*   If `Concrete`'s implementation ever has to change, you don't have to rewrite
    everywhere it is used. Instead, you can absorb the change in your
    implementation of the interface, and your other code and tests will be
    insulated from this change.

Some people worry that if everyone is practicing this technique, they will end
up writing lots of redundant code. This concern is totally understandable.
However, there are two reasons why it may not be the case:

*   Different projects may need to use `Concrete` in different ways, so the best
    interfaces for them will be different. Therefore, each of them will have its
    own domain-specific interface on top of `Concrete`, and they will not be the
    same code.
*   If enough projects want to use the same interface, they can always share it,
    just like they have been sharing `Concrete`. You can check in the interface
    and the adaptor somewhere near `Concrete` (perhaps in a `contrib`
    sub-directory) and let many projects use it.

You need to weigh the pros and cons carefully for your particular problem, but
I'd like to assure you that the Java community has been practicing this for a
long time and it's a proven effective technique applicable in a wide variety of
situations. :-)

### Delegating Calls to a Fake {#DelegatingToFake}

Some times you have a non-trivial fake implementation of an interface. For
example:

```cpp
class Foo {
 public:
  virtual ~Foo() {}
  virtual char DoThis(int n) = 0;
  virtual void DoThat(const char* s, int* p) = 0;
};

class FakeFoo : public Foo {
 public:
  char DoThis(int n) override {
    return (n > 0) ? '+' :
           (n < 0) ? '-' : '0';
  }

  void DoThat(const char* s, int* p) override {
    *p = strlen(s);
  }
};
```

Now you want to mock this interface such that you can set expectations on it.
However, you also want to use `FakeFoo` for the default behavior, as duplicating
it in the mock object is, well, a lot of work.

When you define the mock class using gMock, you can have it delegate its default
action to a fake class you already have, using this pattern:

```cpp
class MockFoo : public Foo {
 public:
  // Normal mock method definitions using gMock.
  MOCK_METHOD(char, DoThis, (int n), (override));
  MOCK_METHOD(void, DoThat, (const char* s, int* p), (override));

  // Delegates the default actions of the methods to a FakeFoo object.
  // This must be called *before* the custom ON_CALL() statements.
  void DelegateToFake() {
    ON_CALL(*this, DoThis).WillByDefault([this](int n) {
      return fake_.DoThis(n);
    });
    ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) {
      fake_.DoThat(s, p);
    });
  }

 private:
  FakeFoo fake_;  // Keeps an instance of the fake in the mock.
};
```

With that, you can use `MockFoo` in your tests as usual. Just remember that if
you don't explicitly set an action in an `ON_CALL()` or `EXPECT_CALL()`, the
fake will be called upon to do it.:

```cpp
using ::testing::_;

TEST(AbcTest, Xyz) {
  MockFoo foo;

  foo.DelegateToFake();  // Enables the fake for delegation.

  // Put your ON_CALL(foo, ...)s here, if any.

  // No action specified, meaning to use the default action.
  EXPECT_CALL(foo, DoThis(5));
  EXPECT_CALL(foo, DoThat(_, _));

  int n = 0;
  EXPECT_EQ('+', foo.DoThis(5));  // FakeFoo::DoThis() is invoked.
  foo.DoThat("Hi", &n);  // FakeFoo::DoThat() is invoked.
  EXPECT_EQ(2, n);
}
```

**Some tips:**

*   If you want, you can still override the default action by providing your own
    `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`.
*   In `DelegateToFake()`, you only need to delegate the methods whose fake
    implementation you intend to use.

*   The general technique discussed here works for overloaded methods, but
    you'll need to tell the compiler which version you mean. To disambiguate a
    mock function (the one you specify inside the parentheses of `ON_CALL()`),
    use [this technique](#SelectOverload); to disambiguate a fake function (the
    one you place inside `Invoke()`), use a `static_cast` to specify the
    function's type. For instance, if class `Foo` has methods `char DoThis(int
    n)` and `bool DoThis(double x) const`, and you want to invoke the latter,
    you need to write `Invoke(&fake_, static_cast<bool (FakeFoo::*)(double)
    const>(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)`
    (The strange-looking thing inside the angled brackets of `static_cast` is
    the type of a function pointer to the second `DoThis()` method.).

*   Having to mix a mock and a fake is often a sign of something gone wrong.
    Perhaps you haven't got used to the interaction-based way of testing yet. Or
    perhaps your interface is taking on too many roles and should be split up.
    Therefore, **don't abuse this**. We would only recommend to do it as an
    intermediate step when you are refactoring your code.

Regarding the tip on mixing a mock and a fake, here's an example on why it may
be a bad sign: Suppose you have a class `System` for low-level system
operations. In particular, it does file and I/O operations. And suppose you want
to test how your code uses `System` to do I/O, and you just want the file
operations to work normally. If you mock out the entire `System` class, you'll
have to provide a fake implementation for the file operation part, which
suggests that `System` is taking on too many roles.

Instead, you can define a `FileOps` interface and an `IOOps` interface and split
`System`'s functionalities into the two. Then you can mock `IOOps` without
mocking `FileOps`.

### Delegating Calls to a Real Object

When using testing doubles (mocks, fakes, stubs, and etc), sometimes their
behaviors will differ from those of the real objects. This difference could be
either intentional (as in simulating an error such that you can test the error
handling code) or unintentional. If your mocks have different behaviors than the
real objects by mistake, you could end up with code that passes the tests but
fails in production.

You can use the *delegating-to-real* technique to ensure that your mock has the
same behavior as the real object while retaining the ability to validate calls.
This technique is very similar to the [delegating-to-fake](#DelegatingToFake)
technique, the difference being that we use a real object instead of a fake.
Here's an example:

```cpp
using ::testing::AtLeast;

class MockFoo : public Foo {
 public:
  MockFoo() {
    // By default, all calls are delegated to the real object.
    ON_CALL(*this, DoThis).WillByDefault([this](int n) {
      return real_.DoThis(n);
    });
    ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) {
      real_.DoThat(s, p);
    });
    ...
  }
  MOCK_METHOD(char, DoThis, ...);
  MOCK_METHOD(void, DoThat, ...);
  ...
 private:
  Foo real_;
};

...
  MockFoo mock;
  EXPECT_CALL(mock, DoThis())
      .Times(3);
  EXPECT_CALL(mock, DoThat("Hi"))
      .Times(AtLeast(1));
  ... use mock in test ...
```

With this, gMock will verify that your code made the right calls (with the right
arguments, in the right order, called the right number of times, etc), and a
real object will answer the calls (so the behavior will be the same as in
production). This gives you the best of both worlds.

### Delegating Calls to a Parent Class

Ideally, you should code to interfaces, whose methods are all pure virtual. In
reality, sometimes you do need to mock a virtual method that is not pure (i.e,
it already has an implementation). For example:

```cpp
class Foo {
 public:
  virtual ~Foo();

  virtual void Pure(int n) = 0;
  virtual int Concrete(const char* str) { ... }
};

class MockFoo : public Foo {
 public:
  // Mocking a pure method.
  MOCK_METHOD(void, Pure, (int n), (override));
  // Mocking a concrete method.  Foo::Concrete() is shadowed.
  MOCK_METHOD(int, Concrete, (const char* str), (override));
};
```

Sometimes you may want to call `Foo::Concrete()` instead of
`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub action, or
perhaps your test doesn't need to mock `Concrete()` at all (but it would be
oh-so painful to have to define a new mock class whenever you don't need to mock
one of its methods).

You can call `Foo::Concrete()` inside an action by:

```cpp
...
  EXPECT_CALL(foo, Concrete).WillOnce([&foo](const char* str) {
    return foo.Foo::Concrete(str);
  });
```

or tell the mock object that you don't want to mock `Concrete()`:

```cpp
...
  ON_CALL(foo, Concrete).WillByDefault([&foo](const char* str) {
    return foo.Foo::Concrete(str);
  });
```

(Why don't we just write `{ return foo.Concrete(str); }`? If you do that,
`MockFoo::Concrete()` will be called (and cause an infinite recursion) since
`Foo::Concrete()` is virtual. That's just how C++ works.)

## Using Matchers

### Matching Argument Values Exactly

You can specify exactly which arguments a mock method is expecting:

```cpp
using ::testing::Return;
...
  EXPECT_CALL(foo, DoThis(5))
      .WillOnce(Return('a'));
  EXPECT_CALL(foo, DoThat("Hello", bar));
```

### Using Simple Matchers

You can use matchers to match arguments that have a certain property:

```cpp
using ::testing::NotNull;
using ::testing::Return;
...
  EXPECT_CALL(foo, DoThis(Ge(5)))  // The argument must be >= 5.
      .WillOnce(Return('a'));
  EXPECT_CALL(foo, DoThat("Hello", NotNull()));
      // The second argument must not be NULL.
```

A frequently used matcher is `_`, which matches anything:

```cpp
  EXPECT_CALL(foo, DoThat(_, NotNull()));
```

### Combining Matchers {#CombiningMatchers}

You can build complex matchers from existing ones using `AllOf()`,
`AllOfArray()`, `AnyOf()`, `AnyOfArray()` and `Not()`:

```cpp
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::Ne;
using ::testing::Not;
...
  // The argument must be > 5 and != 10.
  EXPECT_CALL(foo, DoThis(AllOf(Gt(5),
                                Ne(10))));

  // The first argument must not contain sub-string "blah".
  EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")),
                          NULL));
```

Matchers are function objects, and parametrized matchers can be composed just
like any other function. However because their types can be long and rarely
provide meaningful information, it can be easier to express them with C++14
generic lambdas to avoid specifying types. For example,

```cpp
using ::testing::Contains;
using ::testing::Property;

inline constexpr auto HasFoo = [](const auto& f) {
  return Property("foo", &MyClass::foo, Contains(f));
};
...
  EXPECT_THAT(x, HasFoo("blah"));
```

### Casting Matchers {#SafeMatcherCast}

gMock matchers are statically typed, meaning that the compiler can catch your
mistake if you use a matcher of the wrong type (for example, if you use `Eq(5)`
to match a `string` argument). Good for you!

Sometimes, however, you know what you're doing and want the compiler to give you
some slack. One example is that you have a matcher for `long` and the argument
you want to match is `int`. While the two types aren't exactly the same, there
is nothing really wrong with using a `Matcher<long>` to match an `int` - after
all, we can first convert the `int` argument to a `long` losslessly before
giving it to the matcher.

To support this need, gMock gives you the `SafeMatcherCast<T>(m)` function. It
casts a matcher `m` to type `Matcher<T>`. To ensure safety, gMock checks that
(let `U` be the type `m` accepts :

1.  Type `T` can be *implicitly* cast to type `U`;
2.  When both `T` and `U` are built-in arithmetic types (`bool`, integers, and
    floating-point numbers), the conversion from `T` to `U` is not lossy (in
    other words, any value representable by `T` can also be represented by `U`);
    and
3.  When `U` is a reference, `T` must also be a reference (as the underlying
    matcher may be interested in the address of the `U` value).

The code won't compile if any of these conditions isn't met.

Here's one example:

```cpp
using ::testing::SafeMatcherCast;

// A base class and a child class.
class Base { ... };
class Derived : public Base { ... };

class MockFoo : public Foo {
 public:
  MOCK_METHOD(void, DoThis, (Derived* derived), (override));
};

...
  MockFoo foo;
  // m is a Matcher<Base*> we got from somewhere.
  EXPECT_CALL(foo, DoThis(SafeMatcherCast<Derived*>(m)));
```

If you find `SafeMatcherCast<T>(m)` too limiting, you can use a similar function
`MatcherCast<T>(m)`. The difference is that `MatcherCast` works as long as you
can `static_cast` type `T` to type `U`.

`MatcherCast` essentially lets you bypass C++'s type system (`static_cast` isn't
always safe as it could throw away information, for example), so be careful not
to misuse/abuse it.

### Selecting Between Overloaded Functions {#SelectOverload}

If you expect an overloaded function to be called, the compiler may need some
help on which overloaded version it is.

To disambiguate functions overloaded on the const-ness of this object, use the
`Const()` argument wrapper.

```cpp
using ::testing::ReturnRef;

class MockFoo : public Foo {
  ...
  MOCK_METHOD(Bar&, GetBar, (), (override));
  MOCK_METHOD(const Bar&, GetBar, (), (const, override));
};

...
  MockFoo foo;
  Bar bar1, bar2;
  EXPECT_CALL(foo, GetBar())         // The non-const GetBar().
      .WillOnce(ReturnRef(bar1));
  EXPECT_CALL(Const(foo), GetBar())  // The const GetBar().
      .WillOnce(ReturnRef(bar2));
```

(`Const()` is defined by gMock and returns a `const` reference to its argument.)

To disambiguate overloaded functions with the same number of arguments but
different argument types, you may need to specify the exact type of a matcher,
either by wrapping your matcher in `Matcher<type>()`, or using a matcher whose
type is fixed (`TypedEq<type>`, `An<type>()`, etc):

```cpp
using ::testing::An;
using ::testing::Matcher;
using ::testing::TypedEq;

class MockPrinter : public Printer {
 public:
  MOCK_METHOD(void, Print, (int n), (override));
  MOCK_METHOD(void, Print, (char c), (override));
};

TEST(PrinterTest, Print) {
  MockPrinter printer;

  EXPECT_CALL(printer, Print(An<int>()));            // void Print(int);
  EXPECT_CALL(printer, Print(Matcher<int>(Lt(5))));  // void Print(int);
  EXPECT_CALL(printer, Print(TypedEq<char>('a')));   // void Print(char);

  printer.Print(3);
  printer.Print(6);
  printer.Print('a');
}
```

### Performing Different Actions Based on the Arguments

When a mock method is called, the *last* matching expectation that's still
active will be selected (think "newer overrides older"). So, you can make a
method do different things depending on its argument values like this:

```cpp
using ::testing::_;
using ::testing::Lt;
using ::testing::Return;
...
  // The default case.
  EXPECT_CALL(foo, DoThis(_))
      .WillRepeatedly(Return('b'));
  // The more specific case.
  EXPECT_CALL(foo, DoThis(Lt(5)))
      .WillRepeatedly(Return('a'));
```

Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will be
returned; otherwise `'b'` will be returned.

### Matching Multiple Arguments as a Whole

Sometimes it's not enough to match the arguments individually. For example, we
may want to say that the first argument must be less than the second argument.
The `With()` clause allows us to match all arguments of a mock function as a
whole. For example,

```cpp
using ::testing::_;
using ::testing::Ne;
using ::testing::Lt;
...
  EXPECT_CALL(foo, InRange(Ne(0), _))
      .With(Lt());
```

says that the first argument of `InRange()` must not be 0, and must be less than
the second argument.

The expression inside `With()` must be a matcher of type `Matcher<std::tuple<A1,
..., An>>`, where `A1`, ..., `An` are the types of the function arguments.

You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms
are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`.

You can use `Args<k1, ..., kn>(m)` to match the `n` selected arguments (as a
tuple) against `m`. For example,

```cpp
using ::testing::_;
using ::testing::AllOf;
using ::testing::Args;
using ::testing::Lt;
...
  EXPECT_CALL(foo, Blah)
      .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 <
z`. Note that in this example, it wasn't necessary to specify the positional
matchers.

As a convenience and example, gMock provides some matchers for 2-tuples,
including the `Lt()` matcher above. See
[Multi-argument Matchers](reference/matchers.md#MultiArgMatchers) for the
complete list.

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
take a `std::tuple` as its argument; gMock will pass the `n` selected arguments
as *one* single tuple to the predicate.

### Using Matchers as Predicates

Have you noticed that a matcher is just a fancy predicate that also knows how to
describe itself? Many existing algorithms take predicates as arguments (e.g.
those defined in STL's `<algorithm>` header), and it would be a shame if gMock
matchers were not allowed to participate.

Luckily, you can use a matcher where a unary predicate functor is expected by
wrapping it inside the `Matches()` function. For example,

```cpp
#include <algorithm>
#include <vector>

using ::testing::Matches;
using ::testing::Ge;

vector<int> v;
...
// How many elements in v are >= 10?
const int count = count_if(v.begin(), v.end(), Matches(Ge(10)));
```

Since you can build complex matchers from simpler ones easily using gMock, this
gives you a way to conveniently construct composite predicates (doing the same
using STL's `<functional>` header is just painful). For example, here's a
predicate that's satisfied by any number that is >= 0, <= 100, and != 50:

```cpp
using testing::AllOf;
using testing::Ge;
using testing::Le;
using testing::Matches;
using testing::Ne;
...
Matches(AllOf(Ge(0), Le(100), Ne(50)))
```

### Using Matchers in googletest Assertions

See [`EXPECT_THAT`](reference/assertions.md#EXPECT_THAT) in the Assertions
Reference.

### Using Predicates as Matchers

gMock provides a set of built-in matchers for matching arguments with expected
values—see the [Matchers Reference](reference/matchers.md) for more information.
In case you find the built-in set lacking, you can use an arbitrary unary
predicate function or functor as a matcher - as long as the predicate accepts a
value of the type you want. You do this by wrapping the predicate inside the
`Truly()` function, for example:

```cpp
using ::testing::Truly;

int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; }
...
  // Bar() must be called with an even number.
  EXPECT_CALL(foo, Bar(Truly(IsEven)));
```

Note that the predicate function / functor doesn't have to return `bool`. It
works as long as the return value can be used as the condition in the statement
`if (condition) ...`.

### Matching Arguments that Are Not Copyable

When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, gMock saves away a copy of
`bar`. When `Foo()` is called later, gMock compares the argument to `Foo()` with
the saved copy of `bar`. This way, you don't need to worry about `bar` being
modified or destroyed after the `EXPECT_CALL()` is executed. The same is true
when you use matchers like `Eq(bar)`, `Le(bar)`, and so on.

But what if `bar` cannot be copied (i.e. has no copy constructor)? You could
define your own matcher function or callback and use it with `Truly()`, as the
previous couple of recipes have shown. Or, you may be able to get away from it
if you can guarantee that `bar` won't be changed after the `EXPECT_CALL()` is
executed. Just tell gMock that it should save a reference to `bar`, instead of a
copy of it. Here's how:

```cpp
using ::testing::Eq;
using ::testing::Lt;
...
  // Expects that Foo()'s argument == bar.
  EXPECT_CALL(mock_obj, Foo(Eq(std::ref(bar))));

  // Expects that Foo()'s argument < bar.
  EXPECT_CALL(mock_obj, Foo(Lt(std::ref(bar))));
```

Remember: if you do this, don't change `bar` after the `EXPECT_CALL()`, or the
result is undefined.

### Validating a Member of an Object

Often a mock function takes a reference to object as an argument. When matching
the argument, you may not want to compare the entire object against a fixed
object, as that may be over-specification. Instead, you may need to validate a
certain member variable or the result of a certain getter method of the object.
You can do this with `Field()` and `Property()`. More specifically,

```cpp
Field(&Foo::bar, m)
```

is a matcher that matches a `Foo` object whose `bar` member variable satisfies
matcher `m`.

```cpp
Property(&Foo::baz, m)
```

is a matcher that matches a `Foo` object whose `baz()` method returns a value
that satisfies matcher `m`.

For example:

| Expression                   | Description                              |
| :--------------------------- | :--------------------------------------- |
| `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`.       |
| `Property(&Foo::name,  StartsWith("John "))` | Matches `x` where `x.name()` starts with  `"John "`. |

Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no argument
and be declared as `const`. Don't use `Property()` against member functions that
you do not own, because taking addresses of functions is fragile and generally
not part of the contract of the function.

`Field()` and `Property()` can also match plain pointers to objects. For
instance,

```cpp
using ::testing::Field;
using ::testing::Ge;
...
Field(&Foo::number, Ge(3))
```

matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, the match
will always fail regardless of the inner matcher.

What if you want to validate more than one members at the same time? Remember
that there are [`AllOf()` and `AllOfArray()`](#CombiningMatchers).

Finally `Field()` and `Property()` provide overloads that take the field or
property names as the first argument to include it in the error message. This
can be useful when creating combined matchers.

```cpp
using ::testing::AllOf;
using ::testing::Field;
using ::testing::Matcher;
using ::testing::SafeMatcherCast;

Matcher<Foo> IsFoo(const Foo& foo) {
  return AllOf(Field("some_field", &Foo::some_field, foo.some_field),
               Field("other_field", &Foo::other_field, foo.other_field),
               Field("last_field", &Foo::last_field, foo.last_field));
}
```

### Validating the Value Pointed to by a Pointer Argument

C++ functions often take pointers as arguments. You can use matchers like
`IsNull()`, `NotNull()`, and other comparison matchers to match a pointer, but
what if you want to make sure the value *pointed to* by the pointer, instead of
the pointer itself, has a certain property? Well, you can use the `Pointee(m)`
matcher.

`Pointee(m)` matches a pointer if and only if `m` matches the value the pointer
points to. For example:

```cpp
using ::testing::Ge;
using ::testing::Pointee;
...
  EXPECT_CALL(foo, Bar(Pointee(Ge(3))));
```

expects `foo.Bar()` to be called with a pointer that points to a value greater
than or equal to 3.

One nice thing about `Pointee()` is that it treats a `NULL` pointer as a match
failure, so you can write `Pointee(m)` instead of

```cpp
using ::testing::AllOf;
using ::testing::NotNull;
using ::testing::Pointee;
...
  AllOf(NotNull(), Pointee(m))
```

without worrying that a `NULL` pointer will crash your test.

Also, did we tell you that `Pointee()` works with both raw pointers **and**
smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)?

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(Pointee(Lt(3)))` matches a pointer that points to a pointer that points
to a number less than 3 (what a mouthful...).

### Defining a Custom Matcher Class {#CustomMatcherClass}

Most matchers can be simply defined using [the MATCHER* macros](#NewMatchers),
which are terse and flexible, and produce good error messages. However, these
macros are not very explicit about the interfaces they create and are not always
suitable, especially for matchers that will be widely reused.

For more advanced cases, you may need to define your own matcher class. A custom
matcher allows you to test a specific invariant property of that object. Let's
take a look at how to do so.

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
class BarPlusBazEqMatcher {
 public:
  using is_gtest_matcher = void;

  explicit BarPlusBazEqMatcher(int expected_sum)
      : expected_sum_(expected_sum) {}

  bool MatchAndExplain(const Foo& foo,
                       std::ostream* /* listener */) const {
    return (foo.bar() + foo.baz()) == expected_sum_;
  }

  void DescribeTo(std::ostream* os) const {
    *os << "bar() + baz() equals " << expected_sum_;
  }

  void DescribeNegationTo(std::ostream* os) const {
    *os << "bar() + baz() does not equal " << expected_sum_;
  }
 private:
  const int expected_sum_;
};

::testing::Matcher<const Foo&> BarPlusBazEq(int expected_sum) {
  return BarPlusBazEqMatcher(expected_sum);
}

...
  Foo foo;
  EXPECT_THAT(foo, BarPlusBazEq(5))...;
```

### Matching Containers

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
`==` operator, you can write `Eq(expected_container)` or simply
`expected_container` to match a container exactly.

Sometimes, though, you may want to be more flexible (for example, the first
element must be an exact match, but the second element can be any positive
number, and so on). Also, containers used in tests often have a small number of
elements, and having to define the expected container out-of-line is a bit of a
hassle.

You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in such
cases:

```cpp
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Gt;
...
  MOCK_METHOD(void, Foo, (const vector<int>& numbers), (override));
...
  EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5)));
```

The above matcher says that the container must have 4 elements, which must be 1,
greater than 0, anything, and 5 respectively.

If you instead write:

```cpp
using ::testing::_;
using ::testing::Gt;
using ::testing::UnorderedElementsAre;
...
  MOCK_METHOD(void, Foo, (const vector<int>& numbers), (override));
...
  EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5)));
```

It means that the container must have 4 elements, which (under some permutation)
must be 1, greater than 0, anything, and 5 respectively.

As an alternative you can place the arguments in a C-style array and use
`ElementsAreArray()` or `UnorderedElementsAreArray()` instead:

```cpp
using ::testing::ElementsAreArray;
...
  // ElementsAreArray accepts an array of element values.
  const int expected_vector1[] = {1, 5, 2, 4, ...};
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1)));

  // Or, an array of element matchers.
  Matcher<int> expected_vector2[] = {1, Gt(2), _, 3, ...};
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2)));
```

In case the array needs to be dynamically created (and therefore the array size
cannot be inferred by the compiler), you can give `ElementsAreArray()` an
additional argument to specify the array size:

```cpp
using ::testing::ElementsAreArray;
...
  int* const expected_vector3 = new int[count];
  ... fill expected_vector3 with values ...
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count)));
```

Use `Pair` when comparing maps or other associative containers.

{% raw %}

```cpp
using ::testing::UnorderedElementsAre;
using ::testing::Pair;
...
  absl::flat_hash_map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
  EXPECT_THAT(m, UnorderedElementsAre(
      Pair("a", 1), Pair("b", 2), Pair("c", 3)));
```

{% endraw %}

**Tips:**

*   `ElementsAre*()` can be used to match *any* container that implements the
    STL iterator pattern (i.e. it has a `const_iterator` type and supports
    `begin()/end()`), not just the ones defined in STL. It will even work with
    container types yet to be written - as long as they follows the above
    pattern.
*   You can use nested `ElementsAre*()` to match nested (multi-dimensional)
    containers.
*   If the container is passed by pointer instead of by reference, just write
    `Pointee(ElementsAre*(...))`.
*   The order of elements *matters* for `ElementsAre*()`. If you are using it
    with containers whose element order are undefined (such as a
    `std::unordered_map`) you should use `UnorderedElementsAre`.

### Sharing Matchers

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
the pointer is copied. When the last matcher that references the implementation
object dies, the implementation object will be deleted.

Therefore, if you have some complex matcher that you want to use again and
again, there is no need to build it every time. Just assign it to a matcher
variable and use that variable repeatedly! For example,

```cpp
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Le;
using ::testing::Matcher;
...
  Matcher<int> in_range = AllOf(Gt(5), Le(10));
  ... use in_range as a matcher in multiple EXPECT_CALLs ...
```

### Matchers must have no side-effects {#PureMatchers}

{: .callout .warning}
WARNING: gMock does not guarantee when or how many times a matcher will be
invoked. Therefore, all matchers must be *purely functional*: they cannot have
any side effects, and the match result must not depend on anything other than
the matcher's parameters and the value being matched.

This requirement must be satisfied no matter how a matcher is defined (e.g., if
it is one of the standard matchers, or a custom matcher). In particular, a
matcher can never call a mock function, as that will affect the state of the
mock object and gMock.

## Setting Expectations

### Knowing When to Expect {#UseOnCall}

**`ON_CALL`** is likely the *single most under-utilized construct* in gMock.

There are basically two constructs for defining the behavior of a mock object:
`ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when
a mock method is called, but <em>doesn't imply any expectation on the method
being called</em>. `EXPECT_CALL` not only defines the behavior, but also sets an
expectation that <em>the method will be called with the given arguments, for the
given number of times</em> (and *in the given order* when you specify the order
too).

Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every
`EXPECT_CALL` adds a constraint on the behavior of the code under test. Having
more constraints than necessary is *baaad* - even worse than not having enough
constraints.

This may be counter-intuitive. How could tests that verify more be worse than
tests that verify less? Isn't verification the whole point of tests?

The answer lies in *what* a test should verify. **A good test verifies the
contract of the code.** If a test over-specifies, it doesn't leave enough
freedom to the implementation. As a result, changing the implementation without
breaking the contract (e.g. refactoring and optimization), which should be
perfectly fine to do, can break such tests. Then you have to spend time fixing
them, only to see them broken again the next time the implementation is changed.

Keep in mind that one doesn't have to verify more than one property in one test.
In fact, **it's a good style to verify only one thing in one test.** If you do
that, a bug will likely break only one or two tests instead of dozens (which
case would you rather debug?). If you are also in the habit of giving tests
descriptive names that tell what they verify, you can often easily guess what's
wrong just from the test log itself.

So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend
to verify that the call is made. For example, you may have a bunch of `ON_CALL`s
in your test fixture to set the common mock behavior shared by all tests in the
same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s
to verify different aspects of the code's behavior. Compared with the style
where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more
resilient to implementational changes (and thus less likely to require
maintenance) and makes the intent of the tests more obvious (so they are easier
to maintain when you do need to maintain them).

If you are bothered by the "Uninteresting mock function call" message printed
when a mock method without an `EXPECT_CALL` is called, you may use a `NiceMock`
instead to suppress all such messages for the mock object, or suppress the
message for specific methods by adding `EXPECT_CALL(...).Times(AnyNumber())`. DO
NOT suppress it by blindly adding an `EXPECT_CALL(...)`, or you'll have a test
that's a pain to maintain.

### Ignoring Uninteresting Calls

If you are not interested in how a mock method is called, just don't say
anything about it. In this case, if the method is ever called, gMock will
perform its default action to allow the test program to continue. If you are not
happy with the default action taken by gMock, you can override it using
`DefaultValue<T>::Set()` (described [here](#DefaultValue)) or `ON_CALL()`.

Please note that once you expressed interest in a particular mock method (via
`EXPECT_CALL()`), all invocations to it must match some expectation. If this
function is called but the arguments don't match any `EXPECT_CALL()` statement,
it will be an error.

### Disallowing Unexpected Calls

If a mock method shouldn't be called at all, explicitly say so:

```cpp
using ::testing::_;
...
  EXPECT_CALL(foo, Bar(_))
      .Times(0);
```

If some calls to the method are allowed, but the rest are not, just list all the
expected calls:

```cpp
using ::testing::AnyNumber;
using ::testing::Gt;
...
  EXPECT_CALL(foo, Bar(5));
  EXPECT_CALL(foo, Bar(Gt(10)))
      .Times(AnyNumber());
```

A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` statements
will be an error.

### Understanding Uninteresting vs Unexpected Calls {#uninteresting-vs-unexpected}

*Uninteresting* calls and *unexpected* calls are different concepts in gMock.
*Very* different.

A call `x.Y(...)` is **uninteresting** if there's *not even a single*
`EXPECT_CALL(x, Y(...))` set. In other words, the test isn't interested in the
`x.Y()` method at all, as evident in that the test doesn't care to say anything
about it.

A call `x.Y(...)` is **unexpected** if there are *some* `EXPECT_CALL(x,
Y(...))`s set, but none of them matches the call. Put another way, the test is
interested in the `x.Y()` method (therefore it explicitly sets some
`EXPECT_CALL` to verify how it's called); however, the verification fails as the
test doesn't expect this particular call to happen.

**An unexpected call is always an error,** as the code under test doesn't behave
the way the test expects it to behave.

**By default, an uninteresting call is not an error,** as it violates no
constraint specified by the test. (gMock's philosophy is that saying nothing
means there is no constraint.) However, it leads to a warning, as it *might*
indicate a problem (e.g. the test author might have forgotten to specify a
constraint).

In gMock, `NiceMock` and `StrictMock` can be used to make a mock class "nice" or
"strict". How does this affect uninteresting calls and unexpected calls?

A **nice mock** suppresses uninteresting call *warnings*. It is less chatty than
the default mock, but otherwise is the same. If a test fails with a default
mock, it will also fail using a nice mock instead. And vice versa. Don't expect
making a mock nice to change the test's result.

A **strict mock** turns uninteresting call warnings into errors. So making a
mock strict may change the test's result.

Let's look at an example:

```cpp
TEST(...) {
  NiceMock<MockDomainRegistry> mock_registry;
  EXPECT_CALL(mock_registry, GetDomainOwner("google.com"))
          .WillRepeatedly(Return("Larry Page"));

  // Use mock_registry in code under test.
  ... &mock_registry ...
}
```

The sole `EXPECT_CALL` here says that all calls to `GetDomainOwner()` must have
`"google.com"` as the argument. If `GetDomainOwner("yahoo.com")` is called, it
will be an unexpected call, and thus an error. *Having a nice mock doesn't
change the severity of an unexpected call.*

So how do we tell gMock that `GetDomainOwner()` can be called with some other
arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`:

```cpp
  EXPECT_CALL(mock_registry, GetDomainOwner(_))
        .Times(AnyNumber());  // catches all other calls to this method.
  EXPECT_CALL(mock_registry, GetDomainOwner("google.com"))
        .WillRepeatedly(Return("Larry Page"));
```

Remember that `_` is the wildcard matcher that matches anything. With this, if
`GetDomainOwner("google.com")` is called, it will do what the second
`EXPECT_CALL` says; if it is called with a different argument, it will do what
the first `EXPECT_CALL` says.

Note that the order of the two `EXPECT_CALL`s is important, as a newer
`EXPECT_CALL` takes precedence over an older one.

For more on uninteresting calls, nice mocks, and strict mocks, read
["The Nice, the Strict, and the Naggy"](#NiceStrictNaggy).

### Ignoring Uninteresting Arguments {#ParameterlessExpectations}

If your test doesn't care about the parameters (it only cares about the number
or order of calls), you can often simply omit the parameter list:

```cpp
  // Expect foo.Bar( ... ) twice with any arguments.
  EXPECT_CALL(foo, Bar).Times(2);

  // Delegate to the given method whenever the factory is invoked.
  ON_CALL(foo_factory, MakeFoo)
      .WillByDefault(&BuildFooForTest);
```

This functionality is only available when a method is not overloaded; to prevent
unexpected behavior it is a compilation error to try to set an expectation on a
method where the specific overload is ambiguous. You can work around this by
supplying a [simpler mock interface](#SimplerInterfaces) than the mocked class
provides.

This pattern is also useful when the arguments are interesting, but match logic
is substantially complex. You can leave the argument list unspecified and use
SaveArg actions to [save the values for later verification](#SaveArgVerify). If
you do that, you can easily differentiate calling the method the wrong number of
times from calling it with the wrong arguments.

### Expecting Ordered Calls {#OrderedCalls}

Although an `EXPECT_CALL()` statement defined later takes precedence when gMock
tries to match a function call with an expectation, by default calls don't have
to happen in the order `EXPECT_CALL()` statements are written. For example, if
the arguments match the matchers in the second `EXPECT_CALL()`, but not those in
the first and third, then the second expectation will be used.

If you would rather have all calls occur in the order of the expectations, put
the `EXPECT_CALL()` statements in a block where you define a variable of type
`InSequence`:

```cpp
using ::testing::_;
using ::testing::InSequence;

  {
    InSequence s;

    EXPECT_CALL(foo, DoThis(5));
    EXPECT_CALL(bar, DoThat(_))
        .Times(2);
    EXPECT_CALL(foo, DoThis(6));
  }
```

In this example, we expect a call to `foo.DoThis(5)`, followed by two calls to
`bar.DoThat()` where the argument can be anything, which are in turn followed by
a call to `foo.DoThis(6)`. If a call occurred out-of-order, gMock will report an
error.

### Expecting Partially Ordered Calls {#PartialOrder}

Sometimes requiring everything to occur in a predetermined order can lead to
brittle tests. For example, we may care about `A` occurring before both `B` and
`C`, but aren't interested in the relative order of `B` and `C`. In this case,
the test should reflect our real intent, instead of being overly constraining.

gMock allows you to impose an arbitrary DAG (directed acyclic graph) on the
calls. One way to express the DAG is to use the
[`After` clause](reference/mocking.md#EXPECT_CALL.After) of `EXPECT_CALL`.

Another way is via the `InSequence()` clause (not the same as the `InSequence`
class), which we borrowed from jMock 2. It's less flexible than `After()`, but
more convenient when you have long chains of sequential calls, as it doesn't
require you to come up with different names for the expectations in the chains.
Here's how it works:

If we view `EXPECT_CALL()` statements as nodes in a graph, and add an edge from
node A to node B wherever A must occur before B, we can get a DAG. We use the
term "sequence" to mean a directed path in this DAG. Now, if we decompose the
DAG into sequences, we just need to know which sequences each `EXPECT_CALL()`
belongs to in order to be able to reconstruct the original DAG.

So, to specify the partial order on the expectations we need to do two things:
first to define some `Sequence` objects, and then for each `EXPECT_CALL()` say
which `Sequence` objects it is part of.

Expectations in the same sequence must occur in the order they are written. For
example,

```cpp
using ::testing::Sequence;
...
  Sequence s1, s2;

  EXPECT_CALL(foo, A())
      .InSequence(s1, s2);
  EXPECT_CALL(bar, B())
      .InSequence(s1);
  EXPECT_CALL(bar, C())
      .InSequence(s2);
  EXPECT_CALL(foo, D())
      .InSequence(s2);
```

specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`):

```text
       +---> B
       |
  A ---|
       |
       +---> C ---> D
```

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.

### Controlling When an Expectation Retires

When a mock method is called, gMock only considers expectations that are still
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

```cpp
using ::testing::_;
using ::testing::Sequence;
...
  Sequence s1, s2;

  EXPECT_CALL(log, Log(WARNING, _, "File too large."))      // #1
      .Times(AnyNumber())
      .InSequence(s1, s2);
  EXPECT_CALL(log, Log(WARNING, _, "Data set is empty."))   // #2
      .InSequence(s1);
  EXPECT_CALL(log, Log(WARNING, _, "User not found."))      // #3
      .InSequence(s2);
```

as soon as either #2 or #3 is matched, #1 will retire. If a warning `"File too
large."` is logged after this, it will be an error.

Note that an expectation doesn't retire automatically when it's saturated. For
example,

```cpp
using ::testing::_;
...
  EXPECT_CALL(log, Log(WARNING, _, _));                     // #1
  EXPECT_CALL(log, Log(WARNING, _, "File too large."));     // #2
```

says that there will be exactly one warning with the message `"File too
large."`. If the second warning contains this message too, #2 will match again
and result in an upper-bound-violated error.

If this is not what you want, you can ask an expectation to retire as soon as it
becomes saturated:

```cpp
using ::testing::_;
...
  EXPECT_CALL(log, Log(WARNING, _, _));                     // #1
  EXPECT_CALL(log, Log(WARNING, _, "File too large."))      // #2
      .RetiresOnSaturation();
```

Here #2 can be used only once, so if you have two warnings with the message
`"File too large."`, the first will match #2 and the second will match #1 -
there will be no error.

## Using Actions

### Returning References from Mock Methods

If a mock function's return type is a reference, you need to use `ReturnRef()`
instead of `Return()` to return a result:

```cpp
using ::testing::ReturnRef;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(Bar&, GetBar, (), (override));
};
...
  MockFoo foo;
  Bar bar;
  EXPECT_CALL(foo, GetBar())
      .WillOnce(ReturnRef(bar));
...
```

### Returning Live Values from Mock Methods

The `Return(x)` action saves a copy of `x` when the action is created, and
always returns the same value whenever it's executed. Sometimes you may want to
instead return the *live* value of `x` (i.e. its value at the time when the
action is *executed*.). Use either `ReturnRef()` or `ReturnPointee()` for this
purpose.

If the mock function's return type is a reference, you can do it using
`ReturnRef(x)`, as shown in the previous recipe ("Returning References from Mock
Methods"). However, gMock doesn't let you use `ReturnRef()` in a mock function
whose return type is not a reference, as doing that usually indicates a user
error. So, what shall you do?

Though you may be tempted, DO NOT use `std::ref()`:

```cpp
using testing::Return;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(int, GetValue, (), (override));
};
...
  int x = 0;
  MockFoo foo;
  EXPECT_CALL(foo, GetValue())
      .WillRepeatedly(Return(std::ref(x)));  // Wrong!
  x = 42;
  EXPECT_EQ(42, foo.GetValue());
```

Unfortunately, it doesn't work here. The above code will fail with error:

```text
Value of: foo.GetValue()
  Actual: 0
Expected: 42
```

The reason is that `Return(*value*)` converts `value` to the actual return type
of the mock function at the time when the action is *created*, not when it is
*executed*. (This behavior was chosen for the action to be safe when `value` is
a proxy object that references some temporary objects.) As a result,
`std::ref(x)` is converted to an `int` value (instead of a `const int&`) when
the expectation is set, and `Return(std::ref(x))` will always return 0.

`ReturnPointee(pointer)` was provided to solve this problem specifically. It
returns the value pointed to by `pointer` at the time the action is *executed*:

```cpp
using testing::ReturnPointee;
...
  int x = 0;
  MockFoo foo;
  EXPECT_CALL(foo, GetValue())
      .WillRepeatedly(ReturnPointee(&x));  // Note the & here.
  x = 42;
  EXPECT_EQ(42, foo.GetValue());  // This will succeed now.
```

### Combining Actions

Want to do more than one thing when a function is called? That's fine. `DoAll()`
allows you to do a sequence of actions every time. Only the return value of the
last action in the sequence will be used.

```cpp
using ::testing::_;
using ::testing::DoAll;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(bool, Bar, (int n), (override));
};
...
  EXPECT_CALL(foo, Bar(_))
      .WillOnce(DoAll(action_1,
                      action_2,
                      ...
                      action_n));
```

### Verifying Complex Arguments {#SaveArgVerify}

If you want to verify that a method is called with a particular argument but the
match criteria is complex, it can be difficult to distinguish between
cardinality failures (calling the method the wrong number of times) and argument
match failures. Similarly, if you are matching multiple parameters, it may not
be easy to distinguishing which argument failed to match. For example:

```cpp
  // Not ideal: this could fail because of a problem with arg1 or arg2, or maybe
  // just the method wasn't called.
  EXPECT_CALL(foo, SendValues(_, ElementsAre(1, 4, 4, 7), EqualsProto( ... )));
```

You can instead save the arguments and test them individually:

```cpp
  EXPECT_CALL(foo, SendValues)
      .WillOnce(DoAll(SaveArg<1>(&actual_array), SaveArg<2>(&actual_proto)));
  ... run the test
  EXPECT_THAT(actual_array, ElementsAre(1, 4, 4, 7));
  EXPECT_THAT(actual_proto, EqualsProto( ... ));
```

### Mocking Side Effects {#MockingSideEffects}

Sometimes a method exhibits its effect not via returning a value but via side
effects. For example, it may change some global state or modify an output
argument. To mock side effects, in general you can define your own action by
implementing `::testing::ActionInterface`.

If all you need to do is to change an output argument, the built-in
`SetArgPointee()` action is convenient:

```cpp
using ::testing::_;
using ::testing::SetArgPointee;

class MockMutator : public Mutator {
 public:
  MOCK_METHOD(void, Mutate, (bool mutate, int* value), (override));
  ...
}
...
  MockMutator mutator;
  EXPECT_CALL(mutator, Mutate(true, _))
      .WillOnce(SetArgPointee<1>(5));
```

In this example, when `mutator.Mutate()` is called, we will assign 5 to the
`int` variable pointed to by argument #1 (0-based).

`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
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
`SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the
`Return()` statement last:

```cpp
using ::testing::_;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;

class MockMutator : public Mutator {
 public:
  ...
  MOCK_METHOD(bool, MutateInt, (int* value), (override));
}
...
  MockMutator mutator;
  EXPECT_CALL(mutator, MutateInt(_))
      .WillOnce(DoAll(SetArgPointee<0>(5),
                      Return(true)));
```

Note, however, that if you use the `ReturnOKWith()` method, it will override the
values provided by `SetArgPointee()` in the response parameters of your function
call.

If the output argument is an array, use the `SetArrayArgument<N>(first, last)`
action instead. It copies the elements in source range `[first, last)` to the
array pointed to by the `N`-th (0-based) argument:

```cpp
using ::testing::NotNull;
using ::testing::SetArrayArgument;

class MockArrayMutator : public ArrayMutator {
 public:
  MOCK_METHOD(void, Mutate, (int* values, int num_values), (override));
  ...
}
...
  MockArrayMutator mutator;
  int values[5] = {1, 2, 3, 4, 5};
  EXPECT_CALL(mutator, Mutate(NotNull(), 5))
      .WillOnce(SetArrayArgument<0>(values, values + 5));
```

This also works when the argument is an output iterator:

```cpp
using ::testing::_;
using ::testing::SetArrayArgument;

class MockRolodex : public Rolodex {
 public:
  MOCK_METHOD(void, GetNames, (std::back_insert_iterator<vector<string>>),
              (override));
  ...
}
...
  MockRolodex rolodex;
  vector<string> names = {"George", "John", "Thomas"};
  EXPECT_CALL(rolodex, GetNames(_))
      .WillOnce(SetArrayArgument<0>(names.begin(), names.end()));
```

### 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
`::testing::InSequence` to specify different behaviors before and after the
call:

```cpp
using ::testing::InSequence;
using ::testing::Return;

...
  {
     InSequence seq;
     EXPECT_CALL(my_mock, IsDirty())
         .WillRepeatedly(Return(true));
     EXPECT_CALL(my_mock, Flush());
     EXPECT_CALL(my_mock, IsDirty())
         .WillRepeatedly(Return(false));
  }
  my_mock.FlushIfDirty();
```

This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called
and return `false` afterwards.

If the behavior change is more complex, you can store the effects in a variable
and make a mock method get its return value from that variable:

```cpp
using ::testing::_;
using ::testing::SaveArg;
using ::testing::Return;

ACTION_P(ReturnPointee, p) { return *p; }
...
  int previous_value = 0;
  EXPECT_CALL(my_mock, GetPrevValue)
      .WillRepeatedly(ReturnPointee(&previous_value));
  EXPECT_CALL(my_mock, UpdateValue)
      .WillRepeatedly(SaveArg<0>(&previous_value));
  my_mock.DoSomethingToUpdateValue();
```

Here `my_mock.GetPrevValue()` will always return the argument of the last
`UpdateValue()` call.

### Setting the Default Value for a Return Type {#DefaultValue}

If a mock method's return type is a built-in C++ type or pointer, by default it
will return 0 when invoked. Also, in C++ 11 and above, a mock method whose
return type has a default constructor will return a default-constructed value by
default. You only need to specify an action if this default value doesn't work
for you.

Sometimes, you may want to change this default value, or you may want to specify
a default value for types gMock doesn't know about. You can do this using the
`::testing::DefaultValue` class template:

```cpp
using ::testing::DefaultValue;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(Bar, CalculateBar, (), (override));
};


...
  Bar default_bar;
  // Sets the default return value for type Bar.
  DefaultValue<Bar>::Set(default_bar);

  MockFoo foo;

  // We don't need to specify an action here, as the default
  // return value works for us.
  EXPECT_CALL(foo, CalculateBar());

  foo.CalculateBar();  // This should return default_bar.

  // Unsets the default return value.
  DefaultValue<Bar>::Clear();
```

Please note that changing the default value for a type can make your tests hard
to understand. We recommend you to use this feature judiciously. For example,
you may want to make sure the `Set()` and `Clear()` calls are right next to the
code that uses your mock.

### Setting the Default Actions for a Mock Method

You've learned how to change the default value of a given type. However, this
may be too coarse for your purpose: perhaps you have two mock methods with the
same return type and you want them to have different behaviors. The `ON_CALL()`
macro allows you to customize your mock's behavior at the method level:

```cpp
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Gt;
using ::testing::Return;
...
  ON_CALL(foo, Sign(_))
      .WillByDefault(Return(-1));
  ON_CALL(foo, Sign(0))
      .WillByDefault(Return(0));
  ON_CALL(foo, Sign(Gt(0)))
      .WillByDefault(Return(1));

  EXPECT_CALL(foo, Sign(_))
      .Times(AnyNumber());

  foo.Sign(5);   // This should return 1.
  foo.Sign(-9);  // This should return -1.
  foo.Sign(0);   // This should return 0.
```

As you may have guessed, when there are more than one `ON_CALL()` statements,
the newer ones in the order take precedence over the older ones. In other words,
the **last** one that matches the function arguments will be used. This matching
order allows you to set up the common behavior in a mock object's constructor or
the test fixture's set-up phase and specialize the mock's behavior later.

Note that both `ON_CALL` and `EXPECT_CALL` have the same "later statements take
precedence" rule, but they don't interact. That is, `EXPECT_CALL`s have their
own precedence order distinct from the `ON_CALL` precedence order.

### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions}

If the built-in actions don't suit you, you can use an existing callable
(function, `std::function`, method, functor, lambda) as an action.

```cpp
using ::testing::_; using ::testing::Invoke;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(int, Sum, (int x, int y), (override));
  MOCK_METHOD(bool, ComplexJob, (int x), (override));
};

int CalculateSum(int x, int y) { return x + y; }
int Sum3(int x, int y, int z) { return x + y + z; }

class Helper {
 public:
  bool ComplexJob(int x);
};

...
  MockFoo foo;
  Helper helper;
  EXPECT_CALL(foo, Sum(_, _))
      .WillOnce(&CalculateSum)
      .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1)));
  EXPECT_CALL(foo, ComplexJob(_))
      .WillOnce(Invoke(&helper, &Helper::ComplexJob))
      .WillOnce([] { return true; })
      .WillRepeatedly([](int x) { return x > 0; });

  foo.Sum(5, 6);         // Invokes CalculateSum(5, 6).
  foo.Sum(2, 3);         // Invokes Sum3(1, 2, 3).
  foo.ComplexJob(10);    // Invokes helper.ComplexJob(10).
  foo.ComplexJob(-1);    // Invokes the inline lambda.
```

The only requirement is that the type of the function, etc must be *compatible*
with the signature of the mock function, meaning that the latter's arguments (if
it takes any) can be implicitly converted to the corresponding arguments of the
former, and the former's return type can be implicitly converted to that of the
latter. So, you can invoke something whose type is *not* exactly the same as the
mock function, as long as it's safe to do so - nice, huh?

Note that:

*   The action takes ownership of the callback and will delete it when the
    action itself is destructed.
*   If the type of a callback is derived from a base callback type `C`, you need
    to implicitly cast it to `C` to resolve the overloading, e.g.

    ```cpp
    using ::testing::Invoke;
    ...
      ResultCallback<bool>* is_ok = ...;
      ... Invoke(is_ok) ...;  // This works.

      BlockingClosure* done = new BlockingClosure;
      ... Invoke(implicit_cast<Closure*>(done)) ...;  // The cast is necessary.
    ```

### Using Functions with Extra Info as Actions

The function or functor you call using `Invoke()` must have the same number of
arguments as the mock function you use it for. Sometimes you may have a function
that takes more arguments, and you are willing to pass in the extra arguments
yourself to fill the gap. You can do this in gMock using callbacks with
pre-bound arguments. Here's an example:

```cpp
using ::testing::Invoke;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(char, DoThis, (int n), (override));
};

char SignOfSum(int x, int y) {
  const int sum = x + y;
  return (sum > 0) ? '+' : (sum < 0) ? '-' : '0';
}

TEST_F(FooTest, Test) {
  MockFoo foo;

  EXPECT_CALL(foo, DoThis(2))
      .WillOnce(Invoke(NewPermanentCallback(SignOfSum, 5)));
  EXPECT_EQ('+', foo.DoThis(2));  // Invokes SignOfSum(5, 2).
}
```

### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments

`Invoke()` passes the mock function's arguments to the function, etc being
invoked such that the callee has the full context of the call to work with. If
the invoked function is not interested in some or all of the arguments, it can
simply ignore them.

Yet, a common pattern is that a test author wants to invoke a function without
the arguments of the mock function. She could do that using a wrapper function
that throws away the arguments before invoking an underlining nullary function.
Needless to say, this can be tedious and obscures the intent of the test.

There are two solutions to this problem. First, you can pass any callable of
zero args as an action. Alternatively, use `InvokeWithoutArgs()`, which is like
`Invoke()` except that it doesn't pass the mock function's arguments to the
callee. Here's an example of each:

```cpp
using ::testing::_;
using ::testing::InvokeWithoutArgs;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(bool, ComplexJob, (int n), (override));
};

bool Job1() { ... }
bool Job2(int n, char c) { ... }

...
  MockFoo foo;
  EXPECT_CALL(foo, ComplexJob(_))
      .WillOnce([] { Job1(); });
      .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a')));

  foo.ComplexJob(10);  // Invokes Job1().
  foo.ComplexJob(20);  // Invokes Job2(5, 'a').
```

Note that:

*   The action takes ownership of the callback and will delete it when the
    action itself is destructed.
*   If the type of a callback is derived from a base callback type `C`, you need
    to implicitly cast it to `C` to resolve the overloading, e.g.

    ```cpp
    using ::testing::InvokeWithoutArgs;
    ...
      ResultCallback<bool>* is_ok = ...;
      ... InvokeWithoutArgs(is_ok) ...;  // This works.

      BlockingClosure* done = ...;
      ... InvokeWithoutArgs(implicit_cast<Closure*>(done)) ...;
      // The cast is necessary.
    ```

### Invoking an Argument of the Mock Function

Sometimes a mock function will receive a function pointer, a functor (in other
words, a "callable") as an argument, e.g.

```cpp
class MockFoo : public Foo {
 public:
  MOCK_METHOD(bool, DoThis, (int n, (ResultCallback1<bool, int>* callback)),
              (override));
};
```

and you may want to invoke this callable argument:

```cpp
using ::testing::_;
...
  MockFoo foo;
  EXPECT_CALL(foo, DoThis(_, _))
      .WillOnce(...);
      // Will execute callback->Run(5), where callback is the
      // second argument DoThis() receives.
```

{: .callout .note}
NOTE: The section below is legacy documentation from before C++ had lambdas:

Arghh, you need to refer to a mock function argument but C++ has no lambda
(yet), so you have to define your own action. :-( Or do you really?

Well, gMock has an action to solve *exactly* this problem:

```cpp
InvokeArgument<N>(arg_1, arg_2, ..., arg_m)
```

will invoke the `N`-th (0-based) argument the mock function receives, with
`arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is a function
pointer, a functor, or a callback. gMock handles them all.

With that, you could write:

```cpp
using ::testing::_;
using ::testing::InvokeArgument;
...
  EXPECT_CALL(foo, DoThis(_, _))
      .WillOnce(InvokeArgument<1>(5));
      // Will execute callback->Run(5), where callback is the
      // second argument DoThis() receives.
```

What if the callable takes an argument by reference? No problem - just wrap it
inside `std::ref()`:

```cpp
  ...
  MOCK_METHOD(bool, Bar,
              ((ResultCallback2<bool, int, const Helper&>* callback)),
              (override));
  ...
  using ::testing::_;
  using ::testing::InvokeArgument;
  ...
  MockFoo foo;
  Helper helper;
  ...
  EXPECT_CALL(foo, Bar(_))
      .WillOnce(InvokeArgument<0>(5, std::ref(helper)));
      // std::ref(helper) guarantees that a reference to helper, not a copy of
      // it, will be passed to the callback.
```

What if the callable takes an argument by reference and we do **not** wrap the
argument in `std::ref()`? Then `InvokeArgument()` will *make a copy* of the
argument, and pass a *reference to the copy*, instead of a reference to the
original value, to the callable. This is especially handy when the argument is a
temporary value:

```cpp
  ...
  MOCK_METHOD(bool, DoThat, (bool (*f)(const double& x, const string& s)),
              (override));
  ...
  using ::testing::_;
  using ::testing::InvokeArgument;
  ...
  MockFoo foo;
  ...
  EXPECT_CALL(foo, DoThat(_))
      .WillOnce(InvokeArgument<0>(5.0, string("Hi")));
      // Will execute (*f)(5.0, string("Hi")), where f is the function pointer
      // DoThat() receives.  Note that the values 5.0 and string("Hi") are
      // temporary and dead once the EXPECT_CALL() statement finishes.  Yet
      // it's fine to perform this action later, since a copy of the values
      // are kept inside the InvokeArgument action.
```

### Ignoring an Action's Result

Sometimes you have an action that returns *something*, but you need an action
that returns `void` (perhaps you want to use it in a mock function that returns
`void`, or perhaps it needs to be used in `DoAll()` and it's not the last in the
list). `IgnoreResult()` lets you do that. For example:

```cpp
using ::testing::_;
using ::testing::DoAll;
using ::testing::IgnoreResult;
using ::testing::Return;

int Process(const MyData& data);
string DoSomething();

class MockFoo : public Foo {
 public:
  MOCK_METHOD(void, Abc, (const MyData& data), (override));
  MOCK_METHOD(bool, Xyz, (), (override));
};

  ...
  MockFoo foo;
  EXPECT_CALL(foo, Abc(_))
      // .WillOnce(Invoke(Process));
      // The above line won't compile as Process() returns int but Abc() needs
      // to return void.
      .WillOnce(IgnoreResult(Process));
  EXPECT_CALL(foo, Xyz())
      .WillOnce(DoAll(IgnoreResult(DoSomething),
                      // Ignores the string DoSomething() returns.
                      Return(true)));
```

Note that you **cannot** use `IgnoreResult()` on an action that already returns
`void`. Doing so will lead to ugly compiler errors.

### Selecting an Action's Arguments {#SelectingArgs}

Say you have a mock function `Foo()` that takes seven arguments, and you have a
custom action that you want to invoke when `Foo()` is called. Trouble is, the
custom action only wants three arguments:

```cpp
using ::testing::_;
using ::testing::Invoke;
...
  MOCK_METHOD(bool, Foo,
              (bool visible, const string& name, int x, int y,
               (const map<pair<int, int>>), double& weight, double min_weight,
               double max_wight));
...
bool IsVisibleInQuadrant1(bool visible, int x, int y) {
  return visible && x >= 0 && y >= 0;
}
...
  EXPECT_CALL(mock, Foo)
      .WillOnce(Invoke(IsVisibleInQuadrant1));  // Uh, won't compile. :-(
```

To please the compiler God, you need to define an "adaptor" that has the same
signature as `Foo()` and calls the custom action with the right arguments:

```cpp
using ::testing::_;
using ::testing::Invoke;
...
bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y,
                            const map<pair<int, int>, double>& weight,
                            double min_weight, double max_wight) {
  return IsVisibleInQuadrant1(visible, x, y);
}
...
  EXPECT_CALL(mock, Foo)
      .WillOnce(Invoke(MyIsVisibleInQuadrant1));  // Now it works.
```

But isn't this awkward?

gMock provides a generic *action adaptor*, so you can spend your time minding
more important business than writing your own adaptors. Here's the syntax:

```cpp
WithArgs<N1, N2, ..., Nk>(action)
```

creates an action that passes the arguments of the mock function at the given
indices (0-based) to the inner `action` and performs it. Using `WithArgs`, our
original example can be written as:

```cpp
using ::testing::_;
using ::testing::Invoke;
using ::testing::WithArgs;
...
  EXPECT_CALL(mock, Foo)
      .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1)));  // No need to define your own adaptor.
```

For better readability, gMock also gives you:

*   `WithoutArgs(action)` when the inner `action` takes *no* argument, and
*   `WithArg<N>(action)` (no `s` after `Arg`) when the inner `action` takes
    *one* argument.

As you may have realized, `InvokeWithoutArgs(...)` is just syntactic sugar for
`WithoutArgs(Invoke(...))`.

Here are more tips:

*   The inner action used in `WithArgs` and friends does not have to be
    `Invoke()` -- it can be anything.
*   You can repeat an argument in the argument list if necessary, e.g.
    `WithArgs<2, 3, 3, 5>(...)`.
*   You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`.
*   The types of the selected arguments do *not* have to match the signature of
    the inner action exactly. It works as long as they can be implicitly
    converted to the corresponding arguments of the inner action. For example,
    if the 4-th argument of the mock function is an `int` and `my_action` takes
    a `double`, `WithArg<4>(my_action)` will work.

### Ignoring Arguments in Action Functions

The [selecting-an-action's-arguments](#SelectingArgs) recipe showed us one way
to make a mock function and an action with incompatible argument lists fit
together. The downside is that wrapping the action in `WithArgs<...>()` can get
tedious for people writing the tests.

If you are defining a function (or method, functor, lambda, callback) to be used
with `Invoke*()`, and you are not interested in some of its arguments, an
alternative to `WithArgs` is to declare the uninteresting arguments as `Unused`.
This makes the definition less cluttered and less fragile in case the types of
the uninteresting arguments change. It could also increase the chance the action
function can be reused. For example, given

```cpp
 public:
  MOCK_METHOD(double, Foo, double(const string& label, double x, double y),
              (override));
  MOCK_METHOD(double, Bar, (int index, double x, double y), (override));
```

instead of

```cpp
using ::testing::_;
using ::testing::Invoke;

double DistanceToOriginWithLabel(const string& label, double x, double y) {
  return sqrt(x*x + y*y);
}
double DistanceToOriginWithIndex(int index, double x, double y) {
  return sqrt(x*x + y*y);
}
...
  EXPECT_CALL(mock, Foo("abc", _, _))
      .WillOnce(Invoke(DistanceToOriginWithLabel));
  EXPECT_CALL(mock, Bar(5, _, _))
      .WillOnce(Invoke(DistanceToOriginWithIndex));
```

you could write

```cpp
using ::testing::_;
using ::testing::Invoke;
using ::testing::Unused;

double DistanceToOrigin(Unused, double x, double y) {
  return sqrt(x*x + y*y);
}
...
  EXPECT_CALL(mock, Foo("abc", _, _))
      .WillOnce(Invoke(DistanceToOrigin));
  EXPECT_CALL(mock, Bar(5, _, _))
      .WillOnce(Invoke(DistanceToOrigin));
```

### Sharing Actions

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
efficient. When the last action that references the implementation object dies,
the implementation object will be deleted.

If you have some complex action that you want to use again and again, you may
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
it has been called), you can assign it to an action variable and use that
variable repeatedly. For example:

```cpp
using ::testing::Action;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;
...
  Action<bool(int*)> set_flag = DoAll(SetArgPointee<0>(5),
                                      Return(true));
  ... use set_flag in .WillOnce() and .WillRepeatedly() ...
```

However, if the action has its own state, you may be surprised if you share the
action object. Suppose you have an action factory `IncrementCounter(init)` which
creates an action that increments and returns a counter whose initial value is
`init`, using two actions created from the same expression and using a shared
action will exhibit different behaviors. Example:

```cpp
  EXPECT_CALL(foo, DoThis())
      .WillRepeatedly(IncrementCounter(0));
  EXPECT_CALL(foo, DoThat())
      .WillRepeatedly(IncrementCounter(0));
  foo.DoThis();  // Returns 1.
  foo.DoThis();  // Returns 2.
  foo.DoThat();  // Returns 1 - Blah() uses a different
                 // counter than Bar()'s.
```

versus

```cpp
using ::testing::Action;
...
  Action<int()> increment = IncrementCounter(0);
  EXPECT_CALL(foo, DoThis())
      .WillRepeatedly(increment);
  EXPECT_CALL(foo, DoThat())
      .WillRepeatedly(increment);
  foo.DoThis();  // Returns 1.
  foo.DoThis();  // Returns 2.
  foo.DoThat();  // Returns 3 - the counter is shared.
```

### Testing Asynchronous Behavior

One oft-encountered problem with gMock is that it can be hard to test
asynchronous behavior. Suppose you had a `EventQueue` class that you wanted to
test, and you created a separate `EventDispatcher` interface so that you could
easily mock it out. However, the implementation of the class fired all the
events on a background thread, which made test timings difficult. You could just
insert `sleep()` statements and hope for the best, but that makes your test
behavior nondeterministic. A better way is to use gMock actions and
`Notification` objects to force your asynchronous test to behave synchronously.

```cpp
class MockEventDispatcher : public EventDispatcher {
  MOCK_METHOD(bool, DispatchEvent, (int32), (override));
};

TEST(EventQueueTest, EnqueueEventTest) {
  MockEventDispatcher mock_event_dispatcher;
  EventQueue event_queue(&mock_event_dispatcher);

  const int32 kEventId = 321;
  absl::Notification done;
  EXPECT_CALL(mock_event_dispatcher, DispatchEvent(kEventId))
      .WillOnce([&done] { done.Notify(); });

  event_queue.EnqueueEvent(kEventId);
  done.WaitForNotification();
}
```

In the example above, we set our normal gMock expectations, but then add an
additional action to notify the `Notification` object. Now we can just call
`Notification::WaitForNotification()` in the main thread to wait for the
asynchronous call to finish. After that, our test suite is complete and we can
safely exit.

{: .callout .note}
Note: this example has a downside: namely, if the expectation is not satisfied,
our test will run forever. It will eventually time-out and fail, but it will
take longer and be slightly harder to debug. To alleviate this problem, you can
use `WaitForNotificationWithTimeout(ms)` instead of `WaitForNotification()`.

## Misc Recipes on Using gMock

### Mocking Methods That Use Move-Only Types

C++11 introduced *move-only types*. A move-only-typed value can be moved from
one object to another, but cannot be copied. `std::unique_ptr<T>` is probably
the most commonly used move-only type.

Mocking a method that takes and/or returns move-only types presents some
challenges, but nothing insurmountable. This recipe shows you how you can do it.
Note that the support for move-only method arguments was only introduced to
gMock in April 2017; in older code, you may find more complex
[workarounds](#LegacyMoveOnly) for lack of this feature.

Let’s say we are working on a fictional project that lets one post and share
snippets called “buzzes”. Your code uses these types:

```cpp
enum class AccessLevel { kInternal, kPublic };

class Buzz {
 public:
  explicit Buzz(AccessLevel access) { ... }
  ...
};

class Buzzer {
 public:
  virtual ~Buzzer() {}
  virtual std::unique_ptr<Buzz> MakeBuzz(StringPiece text) = 0;
  virtual bool ShareBuzz(std::unique_ptr<Buzz> buzz, int64_t timestamp) = 0;
  ...
};
```

A `Buzz` object represents a snippet being posted. A class that implements the
`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in
`Buzzer` may return a `unique_ptr<Buzz>` or take a `unique_ptr<Buzz>`. Now we
need to mock `Buzzer` in our tests.

To mock a method that accepts or returns move-only types, you just use the
familiar `MOCK_METHOD` syntax as usual:

```cpp
class MockBuzzer : public Buzzer {
 public:
  MOCK_METHOD(std::unique_ptr<Buzz>, MakeBuzz, (StringPiece text), (override));
  MOCK_METHOD(bool, ShareBuzz, (std::unique_ptr<Buzz> buzz, int64_t timestamp),
              (override));
};
```

Now that we have the mock class defined, we can use it in tests. In the
following code examples, we assume that we have defined a `MockBuzzer` object
named `mock_buzzer_`:

```cpp
  MockBuzzer mock_buzzer_;
```

First let’s see how we can set expectations on the `MakeBuzz()` method, which
returns a `unique_ptr<Buzz>`.

As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or
`.WillRepeatedly()` clause), when that expectation fires, the default action for
that method will be taken. Since `unique_ptr<>` has a default constructor that
returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an
action:

```cpp
  // Use the default action.
  EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"));

  // Triggers the previous EXPECT_CALL.
  EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello"));
```

If you are not happy with the default action, you can tweak it as usual; see
[Setting Default Actions](#OnCall).

If you just need to return a move-only value, you can use it in combination with
`WillOnce`. For example:

```cpp
  EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"))
      .WillOnce(Return(std::make_unique<Buzz>(AccessLevel::kInternal)));
  EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("hello"));
```

Quiz time! What do you think will happen if a `Return` action is performed more
than once (e.g. you write `... .WillRepeatedly(Return(std::move(...)));`)? Come
think of it, after the first time the action runs, the source value will be
consumed (since it’s a move-only value), so the next time around, there’s no
value to move from -- you’ll get a run-time error that `Return(std::move(...))`
can only be run once.

If you need your mock method to do more than just moving a pre-defined value,
remember that you can always use a lambda or a callable object, which can do
pretty much anything you want:

```cpp
  EXPECT_CALL(mock_buzzer_, MakeBuzz("x"))
      .WillRepeatedly([](StringPiece text) {
        return std::make_unique<Buzz>(AccessLevel::kInternal);
      });

  EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
  EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x"));
```

Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be created
and returned. You cannot do this with `Return(std::make_unique<...>(...))`.

That covers returning move-only values; but how do we work with methods
accepting move-only arguments? The answer is that they work normally, although
some actions will not compile when any of method's arguments are move-only. You
can always use `Return`, or a [lambda or functor](#FunctionsAsActions):

```cpp
  using ::testing::Unused;

  EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true));
  EXPECT_TRUE(mock_buzzer_.ShareBuzz(std::make_unique<Buzz>(AccessLevel::kInternal)),
              0);

  EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce(
      [](std::unique_ptr<Buzz> buzz, Unused) { return buzz != nullptr; });
  EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0));
```

Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...)
could in principle support move-only arguments, but the support for this is not
implemented yet. If this is blocking you, please file a bug.

A few actions (e.g. `DoAll`) copy their arguments internally, so they can never
work with non-copyable objects; you'll have to use functors instead.

#### Legacy workarounds for move-only types {#LegacyMoveOnly}

Support for move-only function arguments was only introduced to gMock in April
of 2017. In older code, you may encounter the following workaround for the lack
of this feature (it is no longer necessary - we're including it just for
reference):

```cpp
class MockBuzzer : public Buzzer {
 public:
  MOCK_METHOD(bool, DoShareBuzz, (Buzz* buzz, Time timestamp));
  bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) override {
    return DoShareBuzz(buzz.get(), timestamp);
  }
};
```

The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call
it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of
setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock
method:

```cpp
  MockBuzzer mock_buzzer_;
  EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _));

  // When one calls ShareBuzz() on the MockBuzzer like this, the call is
  // forwarded to DoShareBuzz(), which is mocked.  Therefore this statement
  // will trigger the above EXPECT_CALL.
  mock_buzzer_.ShareBuzz(std::make_unique<Buzz>(AccessLevel::kInternal), 0);
```

### Making the Compilation Faster

Believe it or not, the *vast majority* of the time spent on compiling a mock
class is in generating its constructor and destructor, as they perform
non-trivial tasks (e.g. verification of the expectations). What's more, mock
methods with different signatures have different types and thus their
constructors/destructors need to be generated by the compiler separately. As a
result, if you mock many different types of methods, compiling your mock class
can get really slow.

If you are experiencing slow compilation, you can move the definition of your
mock class' constructor and destructor out of the class body and into a `.cc`
file. This way, even if you `#include` your mock class in N files, the compiler
only needs to generate its constructor and destructor once, resulting in a much
faster compilation.

Let's illustrate the idea using an example. Here's the definition of a mock
class before applying this recipe:

```cpp
// File mock_foo.h.
...
class MockFoo : public Foo {
 public:
  // Since we don't declare the constructor or the destructor,
  // the compiler will generate them in every translation unit
  // where this mock class is used.

  MOCK_METHOD(int, DoThis, (), (override));
  MOCK_METHOD(bool, DoThat, (const char* str), (override));
  ... more mock methods ...
};
```

After the change, it would look like:

```cpp
// File mock_foo.h.
...
class MockFoo : public Foo {
 public:
  // The constructor and destructor are declared, but not defined, here.
  MockFoo();
  virtual ~MockFoo();

  MOCK_METHOD(int, DoThis, (), (override));
  MOCK_METHOD(bool, DoThat, (const char* str), (override));
  ... more mock methods ...
};
```

and

```cpp
// File mock_foo.cc.
#include "path/to/mock_foo.h"

// The definitions may appear trivial, but the functions actually do a
// lot of things through the constructors/destructors of the member
// variables used to implement the mock methods.
MockFoo::MockFoo() {}
MockFoo::~MockFoo() {}
```

### Forcing a Verification

When it's being destroyed, your friendly mock object will automatically verify
that all expectations on it have been satisfied, and will generate googletest
failures if not. This is convenient as it leaves you with one less thing to
worry about. That is, unless you are not sure if your mock object will be
destroyed.

How could it be that your mock object won't eventually be destroyed? Well, it
might be created on the heap and owned by the code you are testing. Suppose
there's a bug in that code and it doesn't delete the mock object properly - you
could end up with a passing test when there's actually a bug.

Using a heap checker is a good idea and can alleviate the concern, but its
implementation is not 100% reliable. So, sometimes you do want to *force* gMock
to verify a mock object before it is (hopefully) destructed. You can do this
with `Mock::VerifyAndClearExpectations(&mock_object)`:

```cpp
TEST(MyServerTest, ProcessesRequest) {
  using ::testing::Mock;

  MockFoo* const foo = new MockFoo;
  EXPECT_CALL(*foo, ...)...;
  // ... other expectations ...

  // server now owns foo.
  MyServer server(foo);
  server.ProcessRequest(...);

  // In case that server's destructor will forget to delete foo,
  // this will verify the expectations anyway.
  Mock::VerifyAndClearExpectations(foo);
}  // server is destroyed when it goes out of scope here.
```

{: .callout .tip}
**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a `bool` to
indicate whether the verification was successful (`true` for yes), so you can
wrap that function call inside a `ASSERT_TRUE()` if there is no point going
further when the verification has failed.

Do not set new expectations after verifying and clearing a mock after its use.
Setting expectations after code that exercises the mock has undefined behavior.
See [Using Mocks in Tests](gmock_for_dummies.md#using-mocks-in-tests) for more
information.

### Using Checkpoints {#UsingCheckPoints}

Sometimes you might want to test a mock object's behavior in phases whose sizes
are each manageable, or you might want to set more detailed expectations about
which API calls invoke which mock functions.

A technique you can use is to put the expectations in a sequence and insert
calls to a dummy "checkpoint" function at specific places. Then you can verify
that the mock function calls do happen at the right time. For example, if you
are exercising the code:

```cpp
  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:

```cpp
using ::testing::MockFunction;

TEST(FooTest, InvokesBarCorrectly) {
  MyMock mock;
  // Class MockFunction<F> has exactly one mock method.  It is named
  // Call() and has type F.
  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")` call must happen before
checkpoint "1", the second `Bar("a")` call must happen after checkpoint "2", and
nothing should happen between the two checkpoints. The explicit checkpoints make
it clear which `Bar("a")` is called by which call to `Foo()`.

### Mocking Destructors

Sometimes you want to make sure a mock object is destructed at the right time,
e.g. after `bar->A()` is called but before `bar->B()` is called. We already know
that you can specify constraints on the [order](#OrderedCalls) of mock function
calls, so all we need to do is to mock the destructor of the mock function.

This sounds simple, except for one problem: a destructor is a special function
with special syntax and special semantics, and the `MOCK_METHOD` macro doesn't
work for it:

```cpp
MOCK_METHOD(void, ~MockFoo, ());  // Won't compile!
```

The good news is that you can use a simple pattern to achieve the same effect.
First, add a mock function `Die()` to your mock class and call it in the
destructor, like this:

```cpp
class MockFoo : public Foo {
  ...
  // Add the following two lines to the mock class.
  MOCK_METHOD(void, Die, ());
  ~MockFoo() override { Die(); }
};
```

(If the name `Die()` clashes with an existing symbol, choose another name.) Now,
we have translated the problem of testing when a `MockFoo` object dies to
testing when its `Die()` method is called:

```cpp
  MockFoo* foo = new MockFoo;
  MockBar* bar = new MockBar;
  ...
  {
    InSequence s;

    // Expects *foo to die after bar->A() and before bar->B().
    EXPECT_CALL(*bar, A());
    EXPECT_CALL(*foo, Die());
    EXPECT_CALL(*bar, B());
  }
```

And that's that.

### Using gMock and Threads {#UsingThreads}

In a **unit** test, it's best if you could isolate and test a piece of code in a
single-threaded context. That avoids race conditions and dead locks, and makes
debugging your test much easier.

Yet most programs are multi-threaded, and sometimes to test something we need to
pound on it from more than one thread. gMock works for this purpose too.

Remember the steps for using a mock:

1.  Create a mock object `foo`.
2.  Set its default actions and expectations using `ON_CALL()` and
    `EXPECT_CALL()`.
3.  The code under test calls methods of `foo`.
4.  Optionally, verify and reset the mock.
5.  Destroy the mock yourself, or let the code under test destroy it. The
    destructor will automatically verify it.

If you follow the following simple rules, your mocks and threads can live
happily together:

*   Execute your *test code* (as opposed to the code being tested) in *one*
    thread. This makes your test easy to follow.
*   Obviously, you can do step #1 without locking.
*   When doing step #2 and #5, make sure no other thread is accessing `foo`.
    Obvious too, huh?
*   #3 and #4 can be done either in one thread or in multiple threads - anyway
    you want. gMock takes care of the locking, so you don't have to do any -
    unless required by your test logic.

If you violate the rules (for example, if you set expectations on a mock while
another thread is calling its methods), you get undefined behavior. That's not
fun, so don't do it.

gMock guarantees that the action for a mock function is done in the same thread
that called the mock function. For example, in

```cpp
  EXPECT_CALL(mock, Foo(1))
      .WillOnce(action1);
  EXPECT_CALL(mock, Foo(2))
      .WillOnce(action2);
```

if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, gMock will
execute `action1` in thread 1 and `action2` in thread 2.

gMock does *not* impose a sequence on actions performed in different threads
(doing so may create deadlocks as the actions may need to cooperate). This means
that the execution of `action1` and `action2` in the above example *may*
interleave. If this is a problem, you should add proper synchronization logic to
`action1` and `action2` to make the test thread-safe.

Also, remember that `DefaultValue<T>` is a global resource that potentially
affects *all* living mock objects in your program. Naturally, you won't want to
mess with it from multiple threads or when there still are mocks in action.

### Controlling How Much Information gMock Prints

When gMock sees something that has the potential of being an error (e.g. a mock
function with no expectation is called, a.k.a. an uninteresting call, which is
allowed but perhaps you forgot to explicitly ban the call), it prints some
warning messages, including the arguments of the function, the return value, and
the stack trace. Hopefully this will remind you to take a look and see if there
is indeed a problem.

Sometimes you are confident that your tests are correct and may not appreciate
such friendly messages. Some other times, you are debugging your tests or
learning about the behavior of the code you are testing, and wish you could
observe every mock call that happens (including argument values, the return
value, and the stack trace). Clearly, one size doesn't fit all.

You can control how much gMock tells you using the `--gmock_verbose=LEVEL`
command-line flag, where `LEVEL` is a string with three possible values:

*   `info`: gMock will print all informational messages, warnings, and errors
    (most verbose). At this setting, gMock will also log any calls to the
    `ON_CALL/EXPECT_CALL` macros. It will include a stack trace in
    "uninteresting call" warnings.
*   `warning`: gMock will print both warnings and errors (less verbose); it will
    omit the stack traces in "uninteresting call" warnings. This is the default.
*   `error`: gMock will print errors only (least verbose).

Alternatively, you can adjust the value of that flag from within your tests like
so:

```cpp
  ::testing::FLAGS_gmock_verbose = "error";
```

If you find gMock printing too many stack frames with its informational or
warning messages, remember that you can control their amount with the
`--gtest_stack_trace_depth=max_depth` flag.

Now, judiciously use the right flag to enable gMock serve you better!

### Gaining Super Vision into Mock Calls

You have a test using gMock. It fails: gMock tells you some expectations aren't
satisfied. However, you aren't sure why: Is there a typo somewhere in the
matchers? Did you mess up the order of the `EXPECT_CALL`s? Or is the code under
test doing something wrong? How can you find out the cause?

Won't it be nice if you have X-ray vision and can actually see the trace of all
`EXPECT_CALL`s and mock method calls as they are made? For each call, would you
like to see its actual argument values and which `EXPECT_CALL` gMock thinks it
matches? If you still need some help to figure out who made these calls, how
about being able to see the complete stack trace at each mock call?

You can unlock this power by running your test with the `--gmock_verbose=info`
flag. For example, given the test program:

```cpp
#include "gmock/gmock.h"

using testing::_;
using testing::HasSubstr;
using testing::Return;

class MockFoo {
 public:
  MOCK_METHOD(void, F, (const string& x, const string& y));
};

TEST(Foo, Bar) {
  MockFoo mock;
  EXPECT_CALL(mock, F(_, _)).WillRepeatedly(Return());
  EXPECT_CALL(mock, F("a", "b"));
  EXPECT_CALL(mock, F("c", HasSubstr("d")));

  mock.F("a", "good");
  mock.F("a", "b");
}
```

if you run it with `--gmock_verbose=info`, you will see this output:

```shell
[ RUN       ] Foo.Bar

foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked
Stack trace: ...

foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked
Stack trace: ...

foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked
Stack trace: ...

foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))...
    Function call: F(@0x7fff7c8dad40"a",@0x7fff7c8dad10"good")
Stack trace: ...

foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))...
    Function call: F(@0x7fff7c8dada0"a",@0x7fff7c8dad70"b")
Stack trace: ...

foo_test.cc:16: Failure
Actual function call count doesn't match EXPECT_CALL(mock, F("c", HasSubstr("d")))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] Foo.Bar
```

Suppose the bug is that the `"c"` in the third `EXPECT_CALL` is a typo and
should actually be `"a"`. With the above message, you should see that the actual
`F("a", "good")` call is matched by the first `EXPECT_CALL`, not the third as
you thought. From that it should be obvious that the third `EXPECT_CALL` is
written wrong. Case solved.

If you are interested in the mock call trace but not the stack traces, you can
combine `--gmock_verbose=info` with `--gtest_stack_trace_depth=0` on the test
command line.

### Running Tests in Emacs

If you build and run your tests in Emacs using the `M-x google-compile` command
(as many googletest users do), the source file locations of gMock and googletest
errors will be highlighted. Just press `<Enter>` on one of them and you'll be
taken to the offending line. Or, you can just type `C-x`` to jump to the next
error.

To make it even easier, you can add the following lines to your `~/.emacs` file:

```text
(global-set-key "\M-m"  'google-compile)  ; m is for make
(global-set-key [M-down] 'next-error)
(global-set-key [M-up]  '(lambda () (interactive) (next-error -1)))
```

Then you can type `M-m` to start a build (if you want to run the test as well,
just make sure `foo_test.run` or `runtests` is in the build command you supply
after typing `M-m`), or `M-up`/`M-down` to move back and forth between errors.

## Extending gMock

### Writing New Matchers Quickly {#NewMatchers}

{: .callout .warning}
WARNING: gMock does not guarantee when or how many times a matcher will be
invoked. Therefore, all matchers must be functionally pure. See
[this section](#PureMatchers) for more details.

The `MATCHER*` family of macros can be used to define custom matchers easily.
The syntax:

```cpp
MATCHER(name, description_string_expression) { statements; }
```

will define a matcher with the given name that executes the statements, which
must return a `bool` to indicate if the match succeeds. Inside the statements,
you can refer to the value being matched by `arg`, and refer to its type by
`arg_type`.

The *description string* is a `string`-typed expression that documents what the
matcher does, and is used to generate the failure message when the match fails.
It can (and should) reference the special `bool` variable `negation`, and should
evaluate to the description of the matcher when `negation` is `false`, or that
of the matcher's negation when `negation` is `true`.

For convenience, we allow the description string to be empty (`""`), in which
case gMock will use the sequence of words in the matcher name as the
description.

For example:

```cpp
MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; }
```

allows you to write

```cpp
  // Expects mock_foo.Bar(n) to be called where n is divisible by 7.
  EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7()));
```

or,

```cpp
  using ::testing::Not;
  ...
  // Verifies that a value is divisible by 7 and the other is not.
  EXPECT_THAT(some_expression, IsDivisibleBy7());
  EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7()));
```

If the above assertions fail, they will print something like:

```shell
  Value of: some_expression
  Expected: is divisible by 7
    Actual: 27
  ...
  Value of: some_other_expression
  Expected: not (is divisible by 7)
    Actual: 21
```

where the descriptions `"is divisible by 7"` and `"not (is divisible by 7)"` are
automatically calculated from the matcher name `IsDivisibleBy7`.

As you may have noticed, the auto-generated descriptions (especially those for
the negation) may not be so great. You can always override them with a `string`
expression of your own:

```cpp
MATCHER(IsDivisibleBy7,
        absl::StrCat(negation ? "isn't" : "is", " divisible by 7")) {
  return (arg % 7) == 0;
}
```

Optionally, you can stream additional information to a hidden argument named
`result_listener` to explain the match result. For example, a better definition
of `IsDivisibleBy7` is:

```cpp
MATCHER(IsDivisibleBy7, "") {
  if ((arg % 7) == 0)
    return true;

  *result_listener << "the remainder is " << (arg % 7);
  return false;
}
```

With this definition, the above assertion will give a better message:

```shell
  Value of: some_expression
  Expected: is divisible by 7
    Actual: 27 (the remainder is 6)
```

You should let `MatchAndExplain()` print *any additional information* that can
help a user understand the match result. Note that it should explain why the
match succeeds in case of a success (unless it's obvious) - this is useful when
the matcher is used inside `Not()`. There is no need to print the argument value
itself, as gMock already prints it for you.

{: .callout .note}
NOTE: The type of the value being matched (`arg_type`) is determined by the
context in which you use the matcher and is supplied to you by the compiler, so
you don't need to worry about declaring it (nor can you). This allows the
matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match
any type where the value of `(arg % 7) == 0` can be implicitly converted to a
`bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an
`int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will
be `unsigned long`; and so on.

### Writing New Parameterized Matchers Quickly

Sometimes you'll want to define a matcher that has parameters. For that you can
use the macro:

```cpp
MATCHER_P(name, param_name, description_string) { statements; }
```

where the description string can be either `""` or a `string` expression that
references `negation` and `param_name`.

For example:

```cpp
MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; }
```

will allow you to write:

```cpp
  EXPECT_THAT(Blah("a"), HasAbsoluteValue(n));
```

which may lead to this message (assuming `n` is 10):

```shell
  Value of: Blah("a")
  Expected: has absolute value 10
    Actual: -9
```

Note that both the matcher description and its parameter are printed, making the
message human-friendly.

In the matcher definition body, you can write `foo_type` to reference the type
of a parameter named `foo`. For example, in the body of
`MATCHER_P(HasAbsoluteValue, value)` above, you can write `value_type` to refer
to the type of `value`.

gMock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to `MATCHER_P10` to
support multi-parameter matchers:

```cpp
MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; }
```

Please note that the custom description string is for a particular *instance* of
the matcher, where the parameters have been bound to actual values. Therefore
usually you'll want the parameter values to be part of the description. gMock
lets you do that by referencing the matcher parameters in the description string
expression.

For example,

```cpp
using ::testing::PrintToString;
MATCHER_P2(InClosedRange, low, hi,
           absl::StrFormat("%s in range [%s, %s]", negation ? "isn't" : "is",
                           PrintToString(low), PrintToString(hi))) {
  return low <= arg && arg <= hi;
}
...
EXPECT_THAT(3, InClosedRange(4, 6));
```

would generate a failure that contains the message:

```shell
  Expected: is in range [4, 6]
```

If you specify `""` as the description, the failure message will contain the
sequence of words in the matcher name followed by the parameter values printed
as a tuple. For example,

```cpp
  MATCHER_P2(InClosedRange, low, hi, "") { ... }
  ...
  EXPECT_THAT(3, InClosedRange(4, 6));
```

would generate a failure that contains the text:

```shell
  Expected: in closed range (4, 6)
```

For the purpose of typing, you can view

```cpp
MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... }
```

as shorthand for

```cpp
template <typename p1_type, ..., typename pk_type>
FooMatcherPk<p1_type, ..., pk_type>
Foo(p1_type p1, ..., pk_type pk) { ... }
```

When you write `Foo(v1, ..., vk)`, the compiler infers the types of the
parameters `v1`, ..., and `vk` for you. If you are not happy with the result of
the type inference, you can specify the types by explicitly instantiating the
template, as in `Foo<long, bool>(5, false)`. As said earlier, you don't get to
(or need to) specify `arg_type` as that's determined by the context in which the
matcher is used.

You can assign the result of expression `Foo(p1, ..., pk)` to a variable of type
`FooMatcherPk<p1_type, ..., pk_type>`. This can be useful when composing
matchers. Matchers that don't have a parameter or have only one parameter have
special types: you can assign `Foo()` to a `FooMatcher`-typed variable, and
assign `Foo(p)` to a `FooMatcherP<p_type>`-typed variable.

While you can instantiate a matcher template with reference types, passing the
parameters by pointer usually makes your code more readable. If, however, you
still want to pass a parameter by reference, be aware that in the failure
message generated by the matcher you will see the value of the referenced object
but not its address.

You can overload matchers with different numbers of parameters:

```cpp
MATCHER_P(Blah, a, description_string_1) { ... }
MATCHER_P2(Blah, a, b, description_string_2) { ... }
```

While it's tempting to always use the `MATCHER*` macros when defining a new
matcher, you should also consider implementing the matcher interface directly
instead (see the recipes that follow), especially if you need to use the matcher
a lot. While these approaches require more work, they give you more control on
the types of the value being matched and the matcher parameters, which in
general leads to better compiler error messages that pay off in the long run.
They also allow overloading matchers based on parameter types (as opposed to
just based on the number of parameters).

### Writing New Monomorphic Matchers

A matcher of argument type `T` implements the matcher interface for `T` and does
two things: it tests whether a value of type `T` matches the matcher, and can
describe what kind of values it matches. The latter ability is used for
generating readable error messages when expectations are violated.

A matcher of `T` must declare a typedef like:

```cpp
using is_gtest_matcher = void;
```

and supports the following operations:

```cpp
// Match a value and optionally explain into an ostream.
bool matched = matcher.MatchAndExplain(value, maybe_os);
// where `value` is of type `T` and
// `maybe_os` is of type `std::ostream*`, where it can be null if the caller
// is not interested in there textual explanation.

matcher.DescribeTo(os);
matcher.DescribeNegationTo(os);
// where `os` is of type `std::ostream*`.
```

If you need a custom matcher but `Truly()` is not a good option (for example,
you may not be happy with the way `Truly(predicate)` describes itself, or you
may want your matcher to be polymorphic as `Eq(value)` is), you can define a
matcher to do whatever you want in two steps: first implement the matcher
interface, and then define a factory function to create a matcher instance. The
second step is not strictly needed but it makes the syntax of using the matcher
nicer.

For example, you can define a matcher to test whether an `int` is divisible by 7
and then use it like this:

```cpp
using ::testing::Matcher;

class DivisibleBy7Matcher {
 public:
  using is_gtest_matcher = void;

  bool MatchAndExplain(int n, std::ostream*) const {
    return (n % 7) == 0;
  }

  void DescribeTo(std::ostream* os) const {
    *os << "is divisible by 7";
  }

  void DescribeNegationTo(std::ostream* os) const {
    *os << "is not divisible by 7";
  }
};

Matcher<int> DivisibleBy7() {
  return DivisibleBy7Matcher();
}

...
  EXPECT_CALL(foo, Bar(DivisibleBy7()));
```

You may improve the matcher message by streaming additional information to the
`os` argument in `MatchAndExplain()`:

```cpp
class DivisibleBy7Matcher {
 public:
  bool MatchAndExplain(int n, std::ostream* os) const {
    const int remainder = n % 7;
    if (remainder != 0 && os != nullptr) {
      *os << "the remainder is " << remainder;
    }
    return remainder == 0;
  }
  ...
};
```

Then, `EXPECT_THAT(x, DivisibleBy7());` may generate a message like this:

```shell
Value of: x
Expected: is divisible by 7
  Actual: 23 (the remainder is 2)
```

{: .callout .tip}
Tip: for convenience, `MatchAndExplain()` can take a `MatchResultListener*`
instead of `std::ostream*`.

### Writing New Polymorphic Matchers

Expanding what we learned above to *polymorphic* matchers is now just as simple
as adding templates in the right place.

```cpp

class NotNullMatcher {
 public:
  using is_gtest_matcher = void;

  // To implement a polymorphic matcher, we just need to make MatchAndExplain a
  // template on its first argument.

  // In this example, we want to use NotNull() with any pointer, so
  // MatchAndExplain() accepts a pointer of any type as its first argument.
  // In general, you can define MatchAndExplain() as an ordinary method or
  // a method template, or even overload it.
  template <typename T>
  bool MatchAndExplain(T* p, std::ostream*) const {
    return p != nullptr;
  }

  // Describes the property of a value matching this matcher.
  void DescribeTo(std::ostream* os) const { *os << "is not NULL"; }

  // Describes the property of a value NOT matching this matcher.
  void DescribeNegationTo(std::ostream* os) const { *os << "is NULL"; }
};

NotNullMatcher NotNull() {
  return NotNullMatcher();
}

...

  EXPECT_CALL(foo, Bar(NotNull()));  // The argument must be a non-NULL pointer.
```

### Legacy Matcher Implementation

Defining matchers used to be somewhat more complicated, in which it required
several supporting classes and virtual functions. To implement a matcher for
type `T` using the legacy API you have to derive from `MatcherInterface<T>` and
call `MakeMatcher` to construct the object.

The interface looks like this:

```cpp
class MatchResultListener {
 public:
  ...
  // Streams x to the underlying ostream; does nothing if the ostream
  // is NULL.
  template <typename T>
  MatchResultListener& operator<<(const T& x);

  // Returns the underlying ostream.
  std::ostream* stream();
};

template <typename T>
class MatcherInterface {
 public:
  virtual ~MatcherInterface();

  // Returns true if and only if the matcher matches x; also explains the match
  // result to 'listener'.
  virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;

  // Describes this matcher to an ostream.
  virtual void DescribeTo(std::ostream* os) const = 0;

  // Describes the negation of this matcher to an ostream.
  virtual void DescribeNegationTo(std::ostream* os) const;
};
```

Fortunately, most of the time you can define a polymorphic matcher easily with
the help of `MakePolymorphicMatcher()`. Here's how you can define `NotNull()` as
an example:

```cpp
using ::testing::MakePolymorphicMatcher;
using ::testing::MatchResultListener;
using ::testing::PolymorphicMatcher;

class NotNullMatcher {
 public:
  // To implement a polymorphic matcher, first define a COPYABLE class
  // that has three members MatchAndExplain(), DescribeTo(), and
  // DescribeNegationTo(), like the following.

  // In this example, we want to use NotNull() with any pointer, so
  // MatchAndExplain() accepts a pointer of any type as its first argument.
  // In general, you can define MatchAndExplain() as an ordinary method or
  // a method template, or even overload it.
  template <typename T>
  bool MatchAndExplain(T* p,
                       MatchResultListener* /* listener */) const {
    return p != NULL;
  }

  // Describes the property of a value matching this matcher.
  void DescribeTo(std::ostream* os) const { *os << "is not NULL"; }

  // Describes the property of a value NOT matching this matcher.
  void DescribeNegationTo(std::ostream* os) const { *os << "is NULL"; }
};

// To construct a polymorphic matcher, pass an instance of the class
// to MakePolymorphicMatcher().  Note the return type.
PolymorphicMatcher<NotNullMatcher> NotNull() {
  return MakePolymorphicMatcher(NotNullMatcher());
}

...

  EXPECT_CALL(foo, Bar(NotNull()));  // The argument must be a non-NULL pointer.
```

{: .callout .note}
**Note:** Your polymorphic matcher class does **not** need to inherit from
`MatcherInterface` or any other class, and its methods do **not** need to be
virtual.

Like in a monomorphic matcher, you may explain the match result by streaming
additional information to the `listener` argument in `MatchAndExplain()`.

### Writing New Cardinalities

A cardinality is used in `Times()` to tell gMock how many times you expect a
call to occur. It doesn't have to be exact. For example, you can say
`AtLeast(5)` or `Between(2, 4)`.

If the [built-in set](gmock_cheat_sheet.md#CardinalityList) of cardinalities
doesn't suit you, you are free to define your own by implementing the following
interface (in namespace `testing`):

```cpp
class CardinalityInterface {
 public:
  virtual ~CardinalityInterface();

  // Returns true if and only if call_count calls will satisfy this cardinality.
  virtual bool IsSatisfiedByCallCount(int call_count) const = 0;

  // Returns true if and only if call_count calls will saturate this
  // cardinality.
  virtual bool IsSaturatedByCallCount(int call_count) const = 0;

  // Describes self to an ostream.
  virtual void DescribeTo(std::ostream* os) const = 0;
};
```

For example, to specify that a call must occur even number of times, you can
write

```cpp
using ::testing::Cardinality;
using ::testing::CardinalityInterface;
using ::testing::MakeCardinality;

class EvenNumberCardinality : public CardinalityInterface {
 public:
  bool IsSatisfiedByCallCount(int call_count) const override {
    return (call_count % 2) == 0;
  }

  bool IsSaturatedByCallCount(int call_count) const override {
    return false;
  }

  void DescribeTo(std::ostream* os) const {
    *os << "called even number of times";
  }
};

Cardinality EvenNumber() {
  return MakeCardinality(new EvenNumberCardinality);
}

...
  EXPECT_CALL(foo, Bar(3))
      .Times(EvenNumber());
```

### Writing New Actions {#QuickNewActions}

If the built-in actions don't work for you, you can easily define your own one.
All you need is a call operator with a signature compatible with the mocked
function. So you can use a lambda:

```
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce([](const int input) { return input * 7; });
EXPECT_EQ(14, mock.AsStdFunction()(2));
```

Or a struct with a call operator (even a templated one):

```
struct MultiplyBy {
  template <typename T>
  T operator()(T arg) { return arg * multiplier; }

  int multiplier;
};

// Then use:
// 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

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
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
completeness.

By writing

```cpp
ACTION(name) { statements; }
```

in a namespace scope (i.e. not inside a class or function), you will define an
action with the given name that executes the statements. The value returned by
`statements` will be used as the return value of the action. Inside the
statements, you can refer to the K-th (0-based) argument of the mock function as
`argK`. For example:

```cpp
ACTION(IncrementArg1) { return ++(*arg1); }
```

allows you to write

```cpp
... WillOnce(IncrementArg1());
```

Note that you don't need to specify the types of the mock function arguments.
Rest assured that your code is type-safe though: you'll get a compiler error if
`*arg1` doesn't support the `++` operator, or if the type of `++(*arg1)` isn't
compatible with the mock function's return type.

Another example:

```cpp
ACTION(Foo) {
  (*arg2)(5);
  Blah();
  *arg1 = 0;
  return arg0;
}
```

defines an action `Foo()` that invokes argument #2 (a function pointer) with 5,
calls function `Blah()`, sets the value pointed to by argument #1 to 0, and
returns argument #0.

For more convenience and flexibility, you can also use the following pre-defined
symbols in the body of `ACTION`:

`argK_type`     | The type of the K-th (0-based) argument of the mock function
:-------------- | :-----------------------------------------------------------
`args`          | All arguments of the mock function as a tuple
`args_type`     | The type of all arguments of the mock function as a tuple
`return_type`   | The return type of the mock function
`function_type` | The type of the mock function

For example, when using an `ACTION` as a stub action for mock function:

```cpp
int DoSomething(bool flag, int* ptr);
```

we have:

Pre-defined Symbol | Is Bound To
------------------ | ---------------------------------
`arg0`             | the value of `flag`
`arg0_type`        | the type `bool`
`arg1`             | the value of `ptr`
`arg1_type`        | the type `int*`
`args`             | the tuple `(flag, ptr)`
`args_type`        | the type `std::tuple<bool, int*>`
`return_type`      | the type `int`
`function_type`    | the type `int(bool, int*)`

#### Legacy macro-based parameterized Actions

Sometimes you'll want to parameterize an action you define. For that we have
another macro

```cpp
ACTION_P(name, param) { statements; }
```

For example,

```cpp
ACTION_P(Add, n) { return arg0 + n; }
```

will allow you to write

```cpp
// Returns argument #0 + 5.
... WillOnce(Add(5));
```

For convenience, we use the term *arguments* for the values used to invoke the
mock function, and the term *parameters* for the values used to instantiate an
action.

Note that you don't need to provide the type of the parameter either. Suppose
the parameter is named `param`, you can also use the gMock-defined symbol
`param_type` to refer to the type of the parameter as inferred by the compiler.
For example, in the body of `ACTION_P(Add, n)` above, you can write `n_type` for
the type of `n`.

gMock also provides `ACTION_P2`, `ACTION_P3`, and etc to support multi-parameter
actions. For example,

```cpp
ACTION_P2(ReturnDistanceTo, x, y) {
  double dx = arg0 - x;
  double dy = arg1 - y;
  return sqrt(dx*dx + dy*dy);
}
```

lets you write

```cpp
... WillOnce(ReturnDistanceTo(5.0, 26.5));
```

You can view `ACTION` as a degenerated parameterized action where the number of
parameters is 0.

You can also easily define actions overloaded on the number of parameters:

```cpp
ACTION_P(Plus, a) { ... }
ACTION_P2(Plus, a, b) { ... }
```

### Restricting the Type of an Argument or Parameter in an ACTION

For maximum brevity and reusability, the `ACTION*` macros don't ask you to
provide the types of the mock function arguments and the action parameters.
Instead, we let the compiler infer the types for us.

Sometimes, however, we may want to be more explicit about the types. There are
several tricks to do that. For example:

```cpp
ACTION(Foo) {
  // Makes sure arg0 can be converted to int.
  int n = arg0;
  ... use n instead of arg0 here ...
}

ACTION_P(Bar, param) {
  // Makes sure the type of arg1 is const char*.
  ::testing::StaticAssertTypeEq<const char*, arg1_type>();

  // Makes sure param can be converted to bool.
  bool flag = param;
}
```

where `StaticAssertTypeEq` is a compile-time assertion in googletest that
verifies two types are the same.

### Writing New Action Templates Quickly

Sometimes you want to give an action explicit template parameters that cannot be
inferred from its value parameters. `ACTION_TEMPLATE()` supports that and can be
viewed as an extension to `ACTION()` and `ACTION_P*()`.

The syntax:

```cpp
ACTION_TEMPLATE(ActionName,
                HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m),
                AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; }
```

defines an action template that takes *m* explicit template parameters and *n*
value parameters, where *m* is in [1, 10] and *n* is in [0, 10]. `name_i` is the
name of the *i*-th template parameter, and `kind_i` specifies whether it's a
`typename`, an integral constant, or a template. `p_i` is the name of the *i*-th
value parameter.

Example:

```cpp
// DuplicateArg<k, T>(output) converts the k-th argument of the mock
// function to type T and copies it to *output.
ACTION_TEMPLATE(DuplicateArg,
                // Note the comma between int and k:
                HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
                AND_1_VALUE_PARAMS(output)) {
  *output = T(std::get<k>(args));
}
```

To create an instance of an action template, write:

```cpp
ActionName<t1, ..., t_m>(v1, ..., v_n)
```

where the `t`s are the template arguments and the `v`s are the value arguments.
The value argument types are inferred by the compiler. For example:

```cpp
using ::testing::_;
...
  int n;
  EXPECT_CALL(mock, Foo).WillOnce(DuplicateArg<1, unsigned char>(&n));
```

If you want to explicitly specify the value argument types, you can provide
additional template arguments:

```cpp
ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n)
```

where `u_i` is the desired type of `v_i`.

`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the number of
value parameters, but not on the number of template parameters. Without the
restriction, the meaning of the following is unclear:

```cpp
  OverloadedAction<int, bool>(x);
```

Are we using a single-template-parameter action where `bool` refers to the type
of `x`, or a two-template-parameter action where the compiler is asked to infer
the type of `x`?

### Using the ACTION Object's Type

If you are writing a function that returns an `ACTION` object, you'll need to
know its type. The type depends on the macro used to define the action and the
parameter types. The rule is relatively simple:


| Given Definition              | Expression          | Has Type              |
| ----------------------------- | ------------------- | --------------------- |
| `ACTION(Foo)`                 | `Foo()`             | `FooAction`           |
| `ACTION_TEMPLATE(Foo, HAS_m_TEMPLATE_PARAMS(...), AND_0_VALUE_PARAMS())` | `Foo<t1, ..., t_m>()` | `FooAction<t1, ..., t_m>` |
| `ACTION_P(Bar, param)`        | `Bar(int_value)`    | `BarActionP<int>`     |
| `ACTION_TEMPLATE(Bar, HAS_m_TEMPLATE_PARAMS(...), AND_1_VALUE_PARAMS(p1))` | `Bar<t1, ..., t_m>(int_value)` | `BarActionP<t1, ..., t_m, int>` |
| `ACTION_P2(Baz, p1, p2)`      | `Baz(bool_value, int_value)` | `BazActionP2<bool, int>` |
| `ACTION_TEMPLATE(Baz, HAS_m_TEMPLATE_PARAMS(...), AND_2_VALUE_PARAMS(p1, p2))` | `Baz<t1, ..., t_m>(bool_value, int_value)` | `BazActionP2<t1, ..., t_m, bool, int>` |
| ...                           | ...                 | ...                   |


Note that we have to pick different suffixes (`Action`, `ActionP`, `ActionP2`,
and etc) for actions with different numbers of value parameters, or the action
definitions cannot be overloaded on the number of them.

### Writing New Monomorphic Actions {#NewMonoActions}

While the `ACTION*` macros are very convenient, sometimes they are
inappropriate. For example, despite the tricks shown in the previous recipes,
they don't let you directly specify the types of the mock function arguments and
the action parameters, which in general leads to unoptimized compiler error
messages that can baffle unfamiliar users. They also don't allow overloading
actions based on parameter types without jumping through some hoops.

An alternative to the `ACTION*` macros is to implement
`::testing::ActionInterface<F>`, where `F` is the type of the mock function in
which the action will be used. For example:

```cpp
template <typename F>
class ActionInterface {
 public:
  virtual ~ActionInterface();

  // Performs the action.  Result is the return type of function type
  // F, and ArgumentTuple is the tuple of arguments of F.
  //

  // For example, if F is int(bool, const string&), then Result would
  // be int, and ArgumentTuple would be std::tuple<bool, const string&>.
  virtual Result Perform(const ArgumentTuple& args) = 0;
};
```

```cpp
using ::testing::_;
using ::testing::Action;
using ::testing::ActionInterface;
using ::testing::MakeAction;

typedef int IncrementMethod(int*);

class IncrementArgumentAction : public ActionInterface<IncrementMethod> {
 public:
  int Perform(const std::tuple<int*>& args) override {
    int* p = std::get<0>(args);  // Grabs the first argument.
    return *p++;
  }
};

Action<IncrementMethod> IncrementArgument() {
  return MakeAction(new IncrementArgumentAction);
}

...
  EXPECT_CALL(foo, Baz(_))
      .WillOnce(IncrementArgument());

  int n = 5;
  foo.Baz(&n);  // Should return 5 and change n to 6.
```

### Writing New Polymorphic Actions {#NewPolyActions}

The previous recipe showed you how to define your own action. This is all good,
except that you need to know the type of the function in which the action will
be used. Sometimes that can be a problem. For example, if you want to use the
action in functions with *different* types (e.g. like `Return()` and
`SetArgPointee()`).

If an action can be used in several types of mock functions, we say it's
*polymorphic*. The `MakePolymorphicAction()` function template makes it easy to
define such an action:

```cpp
namespace testing {
template <typename Impl>
PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl);
}  // namespace testing
```

As an example, let's define an action that returns the second argument in the
mock function's argument list. The first step is to define an implementation
class:

```cpp
class ReturnSecondArgumentAction {
 public:
  template <typename Result, typename ArgumentTuple>
  Result Perform(const ArgumentTuple& args) const {
    // To get the i-th (0-based) argument, use std::get(args).
    return std::get<1>(args);
  }
};
```

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
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,
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
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
class into the polymorphic action we need. It will be convenient to have a
wrapper for this:

```cpp
using ::testing::MakePolymorphicAction;
using ::testing::PolymorphicAction;

PolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() {
  return MakePolymorphicAction(ReturnSecondArgumentAction());
}
```

Now, you can use this polymorphic action the same way you use the built-in ones:

```cpp
using ::testing::_;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(int, DoThis, (bool flag, int n), (override));
  MOCK_METHOD(string, DoThat, (int x, const char* str1, const char* str2),
              (override));
};

  ...
  MockFoo foo;
  EXPECT_CALL(foo, DoThis).WillOnce(ReturnSecondArgument());
  EXPECT_CALL(foo, DoThat).WillOnce(ReturnSecondArgument());
  ...
  foo.DoThis(true, 5);  // Will return 5.
  foo.DoThat(1, "Hi", "Bye");  // Will return "Hi".
```

### Teaching gMock How to Print Your Values

When an uninteresting or unexpected call occurs, gMock prints the argument
values and the stack trace to help you debug. Assertion macros like
`EXPECT_THAT` and `EXPECT_EQ` also print the values in question when the
assertion fails. gMock and googletest do this using googletest's user-extensible
value printer.

This printer knows how to print built-in C++ types, native arrays, STL
containers, and any type that supports the `<<` operator. For other types, it
prints the raw bytes in the value and hopes that you the user can figure it out.
[The GoogleTest advanced guide](advanced.md#teaching-googletest-how-to-print-your-values)
explains how to extend the printer to do a better job at printing your
particular type than to dump the bytes.

## Useful Mocks Created Using gMock

<!--#include file="includes/g3_testing_LOGs.md"-->
<!--#include file="includes/g3_mock_callbacks.md"-->

### Mock std::function {#MockFunction}

`std::function` is a general function type introduced in C++11. It is a
preferred way of passing callbacks to new interfaces. Functions are copyable,
and are not usually passed around by pointer, which makes them tricky to mock.
But fear not - `MockFunction` can help you with that.

`MockFunction<R(T1, ..., Tn)>` has a mock method `Call()` with the signature:

```cpp
  R Call(T1, ..., Tn);
```

It also has a `AsStdFunction()` method, which creates a `std::function` proxy
forwarding to Call:

```cpp
  std::function<R(T1, ..., Tn)> AsStdFunction();
```

To use `MockFunction`, first create `MockFunction` object and set up
expectations on its `Call` method. Then pass proxy obtained from
`AsStdFunction()` to the code you are testing. For example:

```cpp
TEST(FooTest, RunsCallbackWithBarArgument) {
  // 1. Create a mock object.
  MockFunction<int(string)> mock_function;

  // 2. Set expectations on Call() method.
  EXPECT_CALL(mock_function, Call("bar")).WillOnce(Return(1));

  // 3. Exercise code that uses std::function.
  Foo(mock_function.AsStdFunction());
  // Foo's signature can be either of:
  // void Foo(const std::function<int(string)>& fun);
  // void Foo(std::function<int(string)> fun);

  // 4. All expectations will be verified when mock_function
  //     goes out of scope and is destroyed.
}
```

Remember that function objects created with `AsStdFunction()` are just
forwarders. If you create multiple of them, they will share the same set of
expectations.

Although `std::function` supports unlimited number of arguments, `MockFunction`
implementation is limited to ten. If you ever hit that limit... well, your
callback has bigger problems than being mockable. :-)
