Google test is an open source unit testing framework for C++ language, first released by Google in 2008. Over the years, developers at Google kept improving and updating the framework, turning it into a popular tool for C++ developers across the board.
One of the most useful parts of the framework is Google mock, or Gmock – a library that allows creating mock objects for unit testing purposes. It was initially started by Google as a separate project, but due to close integration with Google test, both projects were eventually merged into one.
However, Gmock still can be used with any testing framework of your choosing, either by simply modifying the main function (slightly messier solution, as it sometimes leads to crashes), or by using a Google test event listener API to transfer reports to other framework of your choice (cleaner solution, that requires a little bit more setup).
Use of Gmock makes unit testing much faster and less resource intensive. Mock objects mimic real objects, but provide specific responses. This allows to test rare edge cases (for example, a code that processes an error), or resource-intensive interactions (for example, with a database) in a quick and controlled way. Gmock makes it easy to create mock objects by using a very simple syntax, allowing you to fully focus on testing instead.
Limitations of Gmock
In this case, unit testing was extensively used as a way to find problems early and quickly check for regressions whenever we make changes to the code. Google test and Gmock are part of our regular toolset when it comes to unit testing in C++.
Over the years, developers found themselves constantly running into certain inherent limitations of Gmock:
- Inability to mock global functions. In fact, Gmock developers do not recommend using global functions at all, saying that it leads to modules that are too tightly coupled and offer less flexibility and less reusability. However, the reality of the situation is that in real life project, there is often no way to avoid global functions completely.
- No support for methods with more than 10 arguments. This is a limitation of the way arguments for
MOCK_METHOD
are stored. Gmock uses tr1::tuple
, which limits the number of fields to 10
. Gmock developers, again, do not recommend to even go as far as 10 arguments, instead recommending that you try to limit your arguments up to 6. In reality, though, you often need more than that. A standard workaround is to wrap your arguments in a single structure and pass it as a single argument. However, this is not always convenient, and certainly not pretty.
This limitations gave some trouble, particularly when trying to mock WinAPI functions, and thus we decided to write our own Gmock extensions in order to remove them. Here are the brief descriptions of our solutions:
Gmock-global
You can get it here.
This extension allows mocking of global functions with Gmock. It offers the following features:
- Header-only, easy to include into the project
- Works with Gmock-more-args, allowing to mock global functions with more than 10 arguments
- Syntax is similar to Gmock: you use
MOCK_GLOBAL_FUNC
method and specify the function that you want to mock along with all necessary arguments. You can also use EXPECT_GLOBAL_CALL
similarly to EXPECT_CALL
in order to get the call count of the function. We have some samples of Gmock-global usage in a separate repository on GitHub.
The only issue is that after clauses cannot be used with global functions, and thus you need to use sequences, if you want to specify the expectation order.
Gmock-more-args
You can get it here.
This extension allows Gmock to process methods with more than 10 arguments. Up to 15 arguments are supported. Main features of the extension:
- Header-only, can be easily included into the project
- Works with Gmock-global, allowing to mock global functions with more than 10 arguments
- Has the same syntax as regular Gmock. You use
MOCK_METHODn
, where n is the number of arguments that you want to pass. For example, if you want to mock function with 11 arguments, you can use MOCK_METHOD11()
. You can find some samples of how to use Gmock-more-args on our GitHub.