proxygen
|
Please send your questions to the googlemock discussion group. If you need help with compiler errors, make sure you have tried Google Mock Doctor first.
In order for a method to be mocked, it must be virtual, unless you use the high-perf dependency injection technique.
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:
you'll need to change it to:
(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:
you should move the logic of ExplainMatchResultTo()
into MatchAndExplain()
, using the MatchResultListener
argument where the ::std::ostream
was used:
If your matcher is defined using MakePolymorphicMatcher()
:
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
):
If your polymorphic matcher uses ExplainMatchResultTo()
for better failure messages:
you'll need to move the logic inside ExplainMatchResultTo()
to MatchAndExplain()
:
For more information, you can read these two recipes from the cookbook. As always, you are welcome to post questions on googlemock@googlegroups.com
if you need any help.
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 is how.
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:
To use it, do:
For example:
Or you can run gmd
and copy-n-paste gcc's error messages to it.
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.
If you compile this using Microsoft Visual C++ 2005 SP1:
You may get the following warning:
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:
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:
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:
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.
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.
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.
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:
By changing ~Base()
to virtual, ~Derived()
will be correctly called when delete p
is executed, and the heap checker will be happy.
When people complain about this, often they are referring to code like:
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:
or you can put the sequence of actions in the same expectation:
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.
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
instead of
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.
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() or MakePolymorphicAction(), or you can write a stub function and invoke it using Invoke().
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:
Using the proposed syntax, it would be:
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:
You still need a typedef
if the return type contains an unprotected comma, but that's much rarer.
Other advantages include:
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.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.MOCK_METHOD*
!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 says it excellently. Check it out.
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. :-)
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.
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.
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 for more details and an example.
If you cannot find the answer to your question in this FAQ, there are some other resources you can use:
Please note that creating an issue in the issue tracker 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):