# 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(n, 2);
}
```

**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(foo.GetValue(), 42);
```

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(foo.GetValue(), 42);  // 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 - DoThat() uses a different
                 // counter than DoThis()'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
using ::testing::IsNull;
...
  // Use the default action.
  EXPECT_CALL(mock_buzzer_, MakeBuzz("hello"));

  // Triggers the previous EXPECT_CALL.
  EXPECT_THAT(mock_buzzer_.MakeBuzz("hello"), IsNull());
```

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:

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

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

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

```cpp
MockFunction<int(int)> mock;
EXPECT_CALL(mock, Call).WillOnce([] { return 17; });
EXPECT_EQ(mock.AsStdFunction()(0), 17);
```

When used with `WillOnce`, the callable can assume it will be called at most
once and is allowed to be a move-only type:

```cpp
// 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. :-)
