

Please send your questions to the
[googlemock](http://groups.google.com/group/googlemock) discussion
group. If you need help with compiler errors, make sure you have
tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first.

## When I call a method on my mock object, the method for the real object is invoked instead.  What's the problem? ##

In order for a method to be mocked, it must be _virtual_, unless you use the [high-perf dependency injection technique](CookBook.md#mocking-nonvirtual-methods).

## I wrote some matchers.  After I upgraded to a new version of Google Mock, they no longer compile.  What's going on? ##

After version 1.4.0 of Google Mock was released, we had an idea on how
to make it easier to write matchers that can generate informative
messages efficiently.  We experimented with this idea and liked what
we saw.  Therefore we decided to implement it.

Unfortunately, this means that if you have defined your own matchers
by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`,
your definitions will no longer compile.  Matchers defined using the
`MATCHER*` family of macros are not affected.

Sorry for the hassle if your matchers are affected.  We believe it's
in everyone's long-term interest to make this change sooner than
later.  Fortunately, it's usually not hard to migrate an existing
matcher to the new API.  Here's what you need to do:

If you wrote your matcher like this:
```
// Old matcher definition that doesn't work with the latest
// Google Mock.
using ::testing::MatcherInterface;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetFoo() > 5;
  }
  ...
};
```

you'll need to change it to:
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool MatchAndExplain(MyType value,
                               MatchResultListener* listener) const {
    // Returns true if value matches.
    return value.GetFoo() > 5;
  }
  ...
};
```
(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second
argument of type `MatchResultListener*`.)

If you were also using `ExplainMatchResultTo()` to improve the matcher
message:
```
// Old matcher definition that doesn't work with the lastest
// Google Mock.
using ::testing::MatcherInterface;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetFoo() > 5;
  }

  virtual void ExplainMatchResultTo(MyType value,
                                    ::std::ostream* os) const {
    // Prints some helpful information to os to help
    // a user understand why value matches (or doesn't match).
    *os << "the Foo property is " << value.GetFoo();
  }
  ...
};
```

you should move the logic of `ExplainMatchResultTo()` into
`MatchAndExplain()`, using the `MatchResultListener` argument where
the `::std::ostream` was used:
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool MatchAndExplain(MyType value,
                               MatchResultListener* listener) const {
    // Returns true if value matches.
    *listener << "the Foo property is " << value.GetFoo();
    return value.GetFoo() > 5;
  }
  ...
};
```

If your matcher is defined using `MakePolymorphicMatcher()`:
```
// Old matcher definition that doesn't work with the latest
// Google Mock.
using ::testing::MakePolymorphicMatcher;
...
class MyGreatMatcher {
 public:
  ...
  bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetBar() < 42;
  }
  ...
};
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

you should rename the `Matches()` method to `MatchAndExplain()` and
add a `MatchResultListener*` argument (the same as what you need to do
for matchers defined by implementing `MatcherInterface`):
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MakePolymorphicMatcher;
using ::testing::MatchResultListener;
...
class MyGreatMatcher {
 public:
  ...
  bool MatchAndExplain(MyType value,
                       MatchResultListener* listener) const {
    // Returns true if value matches.
    return value.GetBar() < 42;
  }
  ...
};
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

If your polymorphic matcher uses `ExplainMatchResultTo()` for better
failure messages:
```
// Old matcher definition that doesn't work with the latest
// Google Mock.
using ::testing::MakePolymorphicMatcher;
...
class MyGreatMatcher {
 public:
  ...
  bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetBar() < 42;
  }
  ...
};
void ExplainMatchResultTo(const MyGreatMatcher& matcher,
                          MyType value,
                          ::std::ostream* os) {
  // Prints some helpful information to os to help
  // a user understand why value matches (or doesn't match).
  *os << "the Bar property is " << value.GetBar();
}
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

you'll need to move the logic inside `ExplainMatchResultTo()` to
`MatchAndExplain()`:
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MakePolymorphicMatcher;
using ::testing::MatchResultListener;
...
class MyGreatMatcher {
 public:
  ...
  bool MatchAndExplain(MyType value,
                       MatchResultListener* listener) const {
    // Returns true if value matches.
    *listener << "the Bar property is " << value.GetBar();
    return value.GetBar() < 42;
  }
  ...
};
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

For more information, you can read these
[two](CookBook.md#writing-new-monomorphic-matchers)
[recipes](CookBook.md#writing-new-polymorphic-matchers)
from the cookbook.  As always, you
are welcome to post questions on `googlemock@googlegroups.com` if you
need any help.

## When using Google Mock, do I have to use Google Test as the testing framework?  I have my favorite testing framework and don't want to switch. ##

Google Mock works out of the box with Google Test.  However, it's easy
to configure it to work with any testing framework of your choice.
[Here](ForDummies.md#using-google-mock-with-any-testing-framework) is how.

## How am I supposed to make sense of these horrible template errors? ##

If you are confused by the compiler errors gcc threw at you,
try consulting the _Google Mock Doctor_ tool first.  What it does is to
scan stdin for gcc error messages, and spit out diagnoses on the
problems (we call them diseases) your code has.

To "install", run command:
```
alias gmd='<path to googlemock>/scripts/gmock_doctor.py'
```

To use it, do:
```
<your-favorite-build-command> <your-test> 2>&1 | gmd
```

For example:
```
make my_test 2>&1 | gmd
```

Or you can run `gmd` and copy-n-paste gcc's error messages to it.

## Can I mock a variadic function? ##

You cannot mock a variadic function (i.e. a function taking ellipsis
(`...`) arguments) directly in Google Mock.

The problem is that in general, there is _no way_ for a mock object to
know how many arguments are passed to the variadic method, and what
the arguments' types are.  Only the _author of the base class_ knows
the protocol, and we cannot look into his head.

Therefore, to mock such a function, the _user_ must teach the mock
object how to figure out the number of arguments and their types.  One
way to do it is to provide overloaded versions of the function.

Ellipsis arguments are inherited from C and not really a C++ feature.
They are unsafe to use and don't work with arguments that have
constructors or destructors.  Therefore we recommend to avoid them in
C++ as much as possible.

## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter.  Why? ##

If you compile this using Microsoft Visual C++ 2005 SP1:
```
class Foo {
  ...
  virtual void Bar(const int i) = 0;
};

class MockFoo : public Foo {
  ...
  MOCK_METHOD1(Bar, void(const int i));
};
```
You may get the following warning:
```
warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier
```

This is a MSVC bug.  The same code compiles fine with gcc ,for
example.  If you use Visual C++ 2008 SP1, you would get the warning:
```
warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
```

In C++, if you _declare_ a function with a `const` parameter, the
`const` modifier is _ignored_.  Therefore, the `Foo` base class above
is equivalent to:
```
class Foo {
  ...
  virtual void Bar(int i) = 0;  // int or const int?  Makes no difference.
};
```

In fact, you can _declare_ Bar() with an `int` parameter, and _define_
it with a `const int` parameter.  The compiler will still match them
up.

Since making a parameter `const` is meaningless in the method
_declaration_, we recommend to remove it in both `Foo` and `MockFoo`.
That should workaround the VC bug.

Note that we are talking about the _top-level_ `const` modifier here.
If the function parameter is passed by pointer or reference, declaring
the _pointee_ or _referee_ as `const` is still meaningful.  For
example, the following two declarations are _not_ equivalent:
```
void Bar(int* p);        // Neither p nor *p is const.
void Bar(const int* p);  // p is not const, but *p is.
```

## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it.  What can I do? ##

We've noticed that when the `/clr` compiler flag is used, Visual C++
uses 5~6 times as much memory when compiling a mock class.  We suggest
to avoid `/clr` when compiling native C++ mocks.

## I can't figure out why Google Mock thinks my expectations are not satisfied.  What should I do? ##

You might want to run your test with
`--gmock_verbose=info`.  This flag lets Google Mock print a trace
of every mock function call it receives.  By studying the trace,
you'll gain insights on why the expectations you set are not met.

## How can I assert that a function is NEVER called? ##

```
EXPECT_CALL(foo, Bar(_))
    .Times(0);
```

## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied.  Isn't this redundant? ##

When Google Mock detects a failure, it prints relevant information
(the mock function arguments, the state of relevant expectations, and
etc) to help the user debug.  If another failure is detected, Google
Mock will do the same, including printing the state of relevant
expectations.

Sometimes an expectation's state didn't change between two failures,
and you'll see the same description of the state twice.  They are
however _not_ redundant, as they refer to _different points in time_.
The fact they are the same _is_ interesting information.

## I get a heap check failure when using a mock object, but using a real object is fine.  What can be wrong? ##

Does the class (hopefully a pure interface) you are mocking have a
virtual destructor?

Whenever you derive from a base class, make sure its destructor is
virtual.  Otherwise Bad Things will happen.  Consider the following
code:

```
class Base {
 public:
  // Not virtual, but should be.
  ~Base() { ... }
  ...
};

class Derived : public Base {
 public:
  ...
 private:
  std::string value_;
};

...
  Base* p = new Derived;
  ...
  delete p;  // Surprise! ~Base() will be called, but ~Derived() will not
             // - value_ is leaked.
```

By changing `~Base()` to virtual, `~Derived()` will be correctly
called when `delete p` is executed, and the heap checker
will be happy.

## The "newer expectations override older ones" rule makes writing expectations awkward.  Why does Google Mock do that? ##

When people complain about this, often they are referring to code like:

```
// foo.Bar() should be called twice, return 1 the first time, and return
// 2 the second time.  However, I have to write the expectations in the
// reverse order.  This sucks big time!!!
EXPECT_CALL(foo, Bar())
    .WillOnce(Return(2))
    .RetiresOnSaturation();
EXPECT_CALL(foo, Bar())
    .WillOnce(Return(1))
    .RetiresOnSaturation();
```

The problem is that they didn't pick the **best** way to express the test's
intent.

By default, expectations don't have to be matched in _any_ particular
order.  If you want them to match in a certain order, you need to be
explicit.  This is Google Mock's (and jMock's) fundamental philosophy: it's
easy to accidentally over-specify your tests, and we want to make it
harder to do so.

There are two better ways to write the test spec.  You could either
put the expectations in sequence:

```
// foo.Bar() should be called twice, return 1 the first time, and return
// 2 the second time.  Using a sequence, we can write the expectations
// in their natural order.
{
  InSequence s;
  EXPECT_CALL(foo, Bar())
      .WillOnce(Return(1))
      .RetiresOnSaturation();
  EXPECT_CALL(foo, Bar())
      .WillOnce(Return(2))
      .RetiresOnSaturation();
}
```

or you can put the sequence of actions in the same expectation:

```
// foo.Bar() should be called twice, return 1 the first time, and return
// 2 the second time.
EXPECT_CALL(foo, Bar())
    .WillOnce(Return(1))
    .WillOnce(Return(2))
    .RetiresOnSaturation();
```

Back to the original questions: why does Google Mock search the
expectations (and `ON_CALL`s) from back to front?  Because this
allows a user to set up a mock's behavior for the common case early
(e.g. in the mock's constructor or the test fixture's set-up phase)
and customize it with more specific rules later.  If Google Mock
searches from front to back, this very useful pattern won't be
possible.

## Google Mock prints a warning when a function without EXPECT\_CALL is called, even if I have set its behavior using ON\_CALL.  Would it be reasonable not to show the warning in this case? ##

When choosing between being neat and being safe, we lean toward the
latter.  So the answer is that we think it's better to show the
warning.

Often people write `ON_CALL`s in the mock object's
constructor or `SetUp()`, as the default behavior rarely changes from
test to test.  Then in the test body they set the expectations, which
are often different for each test.  Having an `ON_CALL` in the set-up
part of a test doesn't mean that the calls are expected.  If there's
no `EXPECT_CALL` and the method is called, it's possibly an error.  If
we quietly let the call go through without notifying the user, bugs
may creep in unnoticed.

If, however, you are sure that the calls are OK, you can write

```
EXPECT_CALL(foo, Bar(_))
    .WillRepeatedly(...);
```

instead of

```
ON_CALL(foo, Bar(_))
    .WillByDefault(...);
```

This tells Google Mock that you do expect the calls and no warning should be
printed.

Also, you can control the verbosity using the `--gmock_verbose` flag.
If you find the output too noisy when debugging, just choose a less
verbose level.

## How can I delete the mock function's argument in an action? ##

If you find yourself needing to perform some action that's not
supported by Google Mock directly, remember that you can define your own
actions using
[MakeAction()](CookBook.md#writing-new-actions) or
[MakePolymorphicAction()](CookBook.md#writing_new_polymorphic_actions),
or you can write a stub function and invoke it using
[Invoke()](CookBook.md#using-functions_methods_functors).

## MOCK\_METHODn()'s second argument looks funny.  Why don't you use the MOCK\_METHODn(Method, return\_type, arg\_1, ..., arg\_n) syntax? ##

What?!  I think it's beautiful. :-)

While which syntax looks more natural is a subjective matter to some
extent, Google Mock's syntax was chosen for several practical advantages it
has.

Try to mock a function that takes a map as an argument:
```
virtual int GetSize(const map<int, std::string>& m);
```

Using the proposed syntax, it would be:
```
MOCK_METHOD1(GetSize, int, const map<int, std::string>& m);
```

Guess what?  You'll get a compiler error as the compiler thinks that
`const map<int, std::string>& m` are **two**, not one, arguments. To work
around this you can use `typedef` to give the map type a name, but
that gets in the way of your work.  Google Mock's syntax avoids this
problem as the function's argument types are protected inside a pair
of parentheses:
```
// This compiles fine.
MOCK_METHOD1(GetSize, int(const map<int, std::string>& m));
```

You still need a `typedef` if the return type contains an unprotected
comma, but that's much rarer.

Other advantages include:
  1. `MOCK_METHOD1(Foo, int, bool)` can leave a reader wonder whether the method returns `int` or `bool`, while there won't be such confusion using Google Mock's syntax.
  1. The way Google Mock describes a function type is nothing new, although many people may not be familiar with it.  The same syntax was used in C, and the `function` library in `tr1` uses this syntax extensively.  Since `tr1` will become a part of the new version of STL, we feel very comfortable to be consistent with it.
  1. The function type syntax is also used in other parts of Google Mock's API (e.g. the action interface) in order to make the implementation tractable. A user needs to learn it anyway in order to utilize Google Mock's more advanced features.  We'd as well stick to the same syntax in `MOCK_METHOD*`!

## My code calls a static/global function.  Can I mock it? ##

You can, but you need to make some changes.

In general, if you find yourself needing to mock a static function,
it's a sign that your modules are too tightly coupled (and less
flexible, less reusable, less testable, etc).  You are probably better
off defining a small interface and call the function through that
interface, which then can be easily mocked.  It's a bit of work
initially, but usually pays for itself quickly.

This Google Testing Blog
[post](http://googletesting.blogspot.com/2008/06/defeat-static-cling.html)
says it excellently.  Check it out.

## My mock object needs to do complex stuff.  It's a lot of pain to specify the actions.  Google Mock sucks! ##

I know it's not a question, but you get an answer for free any way. :-)

With Google Mock, you can create mocks in C++ easily.  And people might be
tempted to use them everywhere. Sometimes they work great, and
sometimes you may find them, well, a pain to use. So, what's wrong in
the latter case?

When you write a test without using mocks, you exercise the code and
assert that it returns the correct value or that the system is in an
expected state.  This is sometimes called "state-based testing".

Mocks are great for what some call "interaction-based" testing:
instead of checking the system state at the very end, mock objects
verify that they are invoked the right way and report an error as soon
as it arises, giving you a handle on the precise context in which the
error was triggered.  This is often more effective and economical to
do than state-based testing.

If you are doing state-based testing and using a test double just to
simulate the real object, you are probably better off using a fake.
Using a mock in this case causes pain, as it's not a strong point for
mocks to perform complex actions.  If you experience this and think
that mocks suck, you are just not using the right tool for your
problem. Or, you might be trying to solve the wrong problem. :-)

## I got a warning "Uninteresting function call encountered - default action taken.."  Should I panic? ##

By all means, NO!  It's just an FYI.

What it means is that you have a mock function, you haven't set any
expectations on it (by Google Mock's rule this means that you are not
interested in calls to this function and therefore it can be called
any number of times), and it is called.  That's OK - you didn't say
it's not OK to call the function!

What if you actually meant to disallow this function to be called, but
forgot to write `EXPECT_CALL(foo, Bar()).Times(0)`?  While
one can argue that it's the user's fault, Google Mock tries to be nice and
prints you a note.

So, when you see the message and believe that there shouldn't be any
uninteresting calls, you should investigate what's going on.  To make
your life easier, Google Mock prints the function name and arguments
when an uninteresting call is encountered.

## I want to define a custom action.  Should I use Invoke() or implement the action interface? ##

Either way is fine - you want to choose the one that's more convenient
for your circumstance.

Usually, if your action is for a particular function type, defining it
using `Invoke()` should be easier; if your action can be used in
functions of different types (e.g. if you are defining
`Return(value)`), `MakePolymorphicAction()` is
easiest.  Sometimes you want precise control on what types of
functions the action can be used in, and implementing
`ActionInterface` is the way to go here. See the implementation of
`Return()` in `include/gmock/gmock-actions.h` for an example.

## I'm using the set-argument-pointee action, and the compiler complains about "conflicting return type specified".  What does it mean? ##

You got this error as Google Mock has no idea what value it should return
when the mock method is called.  `SetArgPointee()` says what the
side effect is, but doesn't say what the return value should be.  You
need `DoAll()` to chain a `SetArgPointee()` with a `Return()`.

See this [recipe](CookBook.md#mocking_side_effects) for more details and an example.


## My question is not in your FAQ! ##

If you cannot find the answer to your question in this FAQ, there are
some other resources you can use:

  1. read other [documentation](Documentation.md),
  1. search the mailing list [archive](http://groups.google.com/group/googlemock/topics),
  1. ask it on [googlemock@googlegroups.com](mailto:googlemock@googlegroups.com) and someone will answer it (to prevent spam, we require you to join the [discussion group](http://groups.google.com/group/googlemock) before you can post.).

Please note that creating an issue in the
[issue tracker](https://github.com/google/googletest/issues) is _not_
a good way to get your answer, as it is monitored infrequently by a
very small number of people.

When asking a question, it's helpful to provide as much of the
following information as possible (people cannot help you if there's
not enough information in your question):

  * the version (or the revision number if you check out from SVN directly) of Google Mock you use (Google Mock is under active development, so it's possible that your problem has been solved in a later version),
  * your operating system,
  * the name and version of your compiler,
  * the complete command line flags you give to your compiler,
  * the complete compiler error messages (if the question is about compilation),
  * the _actual_ code (ideally, a minimal but complete program) that has the problem you encounter.
