let’s dev GmbH & Co. KG - The brand for groundbreaking custom software

Blog

Top!

let’s dev | Scroll to top
let’s dev | Scroll to next content item

Hello

let’s dev | Scroll to previous content item
let’s dev Blog | Automated testing of C++ code with Google Test and Google Mock - Part 2
by Arne
13. Juni 2019

Automated testing of C++ code with Google Test and Google Mock - Part 2

Testing applications is also an important part of the development process in the mobile environment. For libraries written in C++, this is made possible by Google Test and Google Mock. After we have already introduced Google Test, we will take a closer look at the mock framework Google Mock in the second part.

Google Mock

As the name suggests, Google Mock is a mock framework. With the help of the framework, it is easy to check whether functions are called as expected and to define what a function that is yet to be implemented should return. Integration and build work analogously to the already presented framework Google Test.

Different types of tests are to be distinguished here. As examples unit tests for testing a component or integration tests, which examine the interaction of several components, are called. For most programming languages, there are also frameworks that significantly facilitate the creation and execution, including for C++.

General

The use of Google Mock is also possible with other test frameworks in addition to Google Test, but the aforementioned integration is then more complex. Therefore, the following explanations refer to the joint use with Google Test.

First of all, the header must be supplemented for this purpose. In addition, it makes sense to make the namespace "testing" visible:

# include <gtest/gtest.h>
# include <gmock/gmock.h>
using namespace testing ;

In order to understand how Google Mock works, it is necessary to first deal with the concept of mock. A mock object implements the same interface as the real object. However, the main difference is that a mock object receives information at runtime about what calls are expected on it and how it should react.

Creation of a mock object

For mocking functions the macros MOCK_METHOD are needed. How these are to be implemented is explained below with an example.

The example is an application that is supposed to display a list of users. This has been created according to the common Model View Controller (MVC) concept and contains a UserListController. This controller is the function that is to be tested. The UI that is set on this controller should react to certain situations. Once user loading is complete, the UI must be updated. If a user has been deleted, it must be removed from the list. Via the controller, a listener can be registered for this purpose. The controller also needs information such as the current account for which it should load the list of users. A DataProvider is injected into the controller for this purpose.

The two interfaces should be defined as follows:

UserListControllerListener
class UserListControllerListener {
public :
virtual void onRefreshData () = 0;
virtual void onRemoveItem (int position ) = 0;
};
UserListControllerDataProvider
class UserListControllerDataProvider {
private :
virtual long getAccountId () = 0;
};

Now the two mocks are defined, which should make it possible to test the behavior of the UserListController interfaces. For this purpose, a new class is created that contains the mock implementation.

UserListControllerListenerMock
class UserListControllerListenerMock : public UserListControllerListener
{
public :
MOCK_METHOD0 ( onRefreshData , void ());
MOCK_METHOD1 ( onRemoveItem , void (int));
};
UserListControllerDataProviderMock
class UserListControllerDataProviderMock : public
UserListControllerDataProvider {
public :
MOCK_METHOD0 ( getAccountId , long ());
};

As can be seen, the mock is implemented in the header, no further code in a cpp is needed for this. However, other things that are less obvious must also be considered. The mock implementation inherits from the UserListControllerDataProviderMock class to be mocked : public UserListControllerDataProvider. The inheritance must be public, otherwise compilation errors may occur. The same applies to the visibility within the class. In the UserListControllerDataProvider the function getAccountId is marked as private but in the associated mock as public. This circumstance is unproblematic in C++, however, since when overwriting a function its visibility can be changed. It is therefore possible to define functions in the code with arbitrary visibility. It must only be paid attention with the implementation of the Mocks to mark these there as public.

The macros themselves have a number at the end e.g. MOCK_METHOD0. The number corresponds to the number of parameters that the function to be mocked has. Again, you get a cryptic error message when compiling if the numbers do not match.

It should also be mentioned that it does not matter for the implementation of the mock whether the functions are purely virtual or not. However, for non-virtual functions the implementation changes slightly.

If you want to save time and don't want to write the mock classes by hand, you can use a Python script provided by Google that can generate the mock implementation from a header. Especially for smaller interfaces, however, the time required should be weighed.

Expectations

For tests that use mocks, it is necessary to define what is expected from each mock. However, it is essential to have the right expectations. If these are too strict, the tests may fail even for changes that have nothing to do with the test in question. However, if expectations are set too loosely, possible errors in the code may possibly be overlooked.

There are several configuration options available for creating Expectations that can be done on a mock:

The terms Matchers, Cardinalities and Actions are given by Google.

Expectations with Cardinalities

A simple expectation is to be considered on the basis of the example described above. It is tested whether the onRefreshData is called. It is assumed that the instance of the UserListControllerListenerMock has already been created and registered on the UserListController as a listener. The instance of the mock object is the mockListener. The defined Expectation is as follows:

EXPECT_CALL ( mockListener , onRefreshData ()). Times (1);
mUserListControler -> loadData ();

The mock listener is told that the function onRefreshData should be called exactly once. If it is called twice or not at all, the test fails. First, the mock must be configured before the call that uses the mock object is executed.

The cardinality can be specified as a direct number. In this case the function is expected to be called exactly once. Zero is also a correct specification. This checks that the function is not called. It is also possible to specify a minimum number:

EXPECT_CALL ( mockListener , onRefreshData ()). Times ( AtLeast (1));

In the above example, the function must be called at least once for the test to be satisfied. However, it is also successful if it is called more than once.

Expectations with Matchers

The following example checks the arguments of the call:

EXPECT_CALL ( mockListener , onRemoveItem (Eq (5)). Times (1) ;

It is to be tested whether the function onRemoveItem is called with the argument 5. Eq is a matcher that already appears in the section Assertion with Matchers (part 1 of the article). So it is possible to perform a whole range of different checks. Matchers are available for many mathematical comparisons (e.g. Ge() is ≥). The existence of objects can be checked with the matchers IsNull() and IsNotNull(). The parameter "_" stands for the wildcard Any. If it is passed instead of Eq(5), the call is valid with any parameter.

Expectations with Actions

Actions can be used to pass specific behaviors to a mock. A simple example of this is the definition of a return value.

EXPECT_CALL ( mockDataProvider , getAccountId (). WillOnce ( Return (17) );

The value 17 is returned during the call of the function. All functions can be used in an EXPECT_CALL. There is also no explicit cardinality given. Google Mock can calculate the cardinality based on the calls of WillOnce.

Multiple Expectations in one Test

It is possible that more than one expectation is included in an integration test. If several Expectations are applied within a function, the order of processing or evaluation is also relevant. Expectations are evaluated in the reverse order of their definition. For the action and cardinality, the first expectation whose matcher fits is always used.

Example for the evaluation of Expectations

Multiple Expectations
EXPECT_CALL ( mockListener , onRemoveItem (_)). Times ( AtLeast (1));
EXPECT_CALL ( mockListener , onRemoveItem (Eq (42) )). Times (3);

Several scenarios are conceivable, resulting in different outcomes. If the function onRemoveItem is called four times with the value 42, this test fails. For all calls with the value 42 the lower expectation takes effect. In the test, Times (3) specifies that the call with 42 is expected three times. However, if the function is called three times with the value 42 without another call, the test fails. Because in the first line it is defined that the function should be called at least once with any other value. Thus, the test is successful if first the value 42 is called three times and then another with 75.

Summary

The explanations show that Google Test and Google Mock are powerful tools for writing automated tests in C++. The libraries can be easily integrated into existing projects using CMake.

Google Test offers a variety of simple ways to write assertions. Tests can be equipped with further information through log messages and scoped traces. In addition, the framework offers the possibility to check more complex topics such as exceptions and aborts.

The biggest limitation of the frameworks, however, is the lack of support for tests of asynchronous functionalities. The fact that Google Test is not considered a Threadsave under some platforms could also pose challenges for users of these platforms.

More articles from our blog

let’s dev Blog | Sketch, Figma & Co. - We take a look at the most popular UI und Prototyping Tools in 2021

Corporate

Sketch, Figma & Co. - We take a look at the most popular UI und Prototyping Tools in 2021

by Ellen

2021-07-15

Read more
let’s dev Blog | Tailwind: An innovative project for the future use of old wind turbines

Corporate

Tailwind: An innovative project for the future use of old wind turbines

by Karl

2021-06-24

Read more
let’s dev Blog |

Corporate

by Julian

2021-06-10

Read more
let’s dev Blog | Smart Prognosis of Energy with Allocation of Resources

Corporate

Smart Prognosis of Energy with Allocation of Resources

by Karl

2021-02-18

Read more
let’s dev Blog | Dasoman - Data-Sovereignty-Manager

Corporate

Dasoman - Data-Sovereignty-Manager

by Karl

2021-01-11

Read more
let’s dev Blog | We look back on the past months - And wish all the best for the coming year 2021!

Corporate

We look back on the past months - And wish all the best for the coming year 2021!

by Julian

2020-12-17

Read more
let’s dev Blog | iOS User Interface Tests

Technical

iOS User Interface Tests

by Nicolas

2020-11-12

Read more
let’s dev Blog | Adobe Max - Online for the first time

Corporate

Adobe Max - Online for the first time

by Julia

2020-10-29

Read more
let’s dev Blog | CAN2BLE

Technical

CAN2BLE

by Raphael

2020-09-24

Read more
let’s dev Blog | Mensch und Computer 2020 - Digital Change in the Flow of Time

Corporate

Mensch und Computer 2020 - Digital Change in the Flow of Time

by UX Team

2020-09-18

Read more
let’s dev Blog | Neumorphism – A new era of user interface design?

Technical

Neumorphism – A new era of user interface design?

by Julian

2020-08-13

Read more
let’s dev Blog | UX Research Part 3 - UX Methods

Technical

UX Research Part 3 - UX Methods

by Elena

2020-05-28

Read more
let’s dev Blog | UX Research Part 2 - What is UCD and what does User Research have to do with it?

Technical

UX Research Part 2 - What is UCD and what does User Research have to do with it?

by Elena

2020-04-23

Read more
let’s dev Blog | go-digital promotes establishment of home office workstations

Corporate

go-digital promotes establishment of home office workstations

by Karl

2020-03-19

Read more
let’s dev Blog | Google Passes - Card Management on Android Devices

Technical

Google Passes - Card Management on Android Devices

by Michelle

2020-03-12

Read more
let’s dev Blog | 100% code coverage in software testing - a reasonable goal?

Technical

100% code coverage in software testing - a reasonable goal?

by Raphael

2020-03-06

Read more
let’s dev Blog | Swift UI - Simple and fast implementation of user interfaces

Technical

Swift UI - Simple and fast implementation of user interfaces

by Tobias

2020-03-02

Read more
let’s dev Blog | In dialog with the business juniors - Exciting insights into business start-ups and digital transformation

Corporate

In dialog with the business juniors - Exciting insights into business start-ups and digital transformation

by Julian

2020-02-27

Read more
let’s dev Blog | Simplified testing of iOS push notifications in the simulator with Xcode 11.4

Technical

Simplified testing of iOS push notifications in the simulator with Xcode 11.4

by Manuel

2020-02-26

Read more
let’s dev Blog | National meeting of the consortium of the SPEAR research project at let's dev in Karlsruhe

Corporate

National meeting of the consortium of the SPEAR research project at let's dev in Karlsruhe

by Karl

2020-01-27

Read more
let’s dev Blog | UX Research Part 1 - Why User Research is so important

Technical

UX Research Part 1 - Why User Research is so important

by Elena

2020-01-23

Read more
let’s dev Blog | Dark Mode

Technical

Dark Mode

by Elisa

2020-01-09

Read more
let’s dev Blog | We wish you a Merry Christmas - And a Happy New Year!

Corporate

We wish you a Merry Christmas - And a Happy New Year!

by Julian

2019-12-20

Read more
let’s dev Blog | Exchange on the topic of digitization with the Business Club Luxembourg at the Embassy of Luxembourg in Berlin

Corporate

Exchange on the topic of digitization with the Business Club Luxembourg at the Embassy of Luxembourg in Berlin

by Karl

2019-12-17

Read more
let’s dev Blog | DaSoMan at the Internet+ Expo in Foshan (China)

Corporate

DaSoMan at the Internet+ Expo in Foshan (China)

by Karl

2019-12-13

Read more
let’s dev Blog | Google Play Console: Pre-Launch Reports

Technical

Google Play Console: Pre-Launch Reports

by Fabian

2019-12-11

Read more
let’s dev Blog | DevFest 2019 in Hamburg

Technical

DevFest 2019 in Hamburg

by Julian

2019-12-05

Read more
let’s dev Blog | Vernissage digital art in the media theater of the Humboldt University Berlin

Corporate

Vernissage digital art in the media theater of the Humboldt University Berlin

by Karl

2019-11-21

Read more
let’s dev Blog | World Usability Day 2019 in Karlsruhe - let's dev supports as main sponsor

Corporate

World Usability Day 2019 in Karlsruhe - let's dev supports as main sponsor

by Aileen

2019-11-11

Read more
let’s dev Blog | Gutted - Open Day at the Alter Schlachthof Karlsruhe 2019

Corporate

Gutted - Open Day at the Alter Schlachthof Karlsruhe 2019

by Julian

2019-09-26

Read more
let’s dev Blog | Mensch und Computer 2019 - Conference on User Experience and Usability in Hamburg

Corporate

Mensch und Computer 2019 - Conference on User Experience and Usability in Hamburg

by Elena

2019-09-17

Read more
let’s dev Blog | Business and Enterprise App Distribution on iOS

Technical

Business and Enterprise App Distribution on iOS

by Aileen

2019-08-05

Read more
let’s dev Blog | Digital Transformation - Chances and Challenges in the Automotive Industry, Agriculture and New Technologies

Corporate

Digital Transformation - Chances and Challenges in the Automotive Industry, Agriculture and New Technologies

by Karl

2019-07-17

Read more
let’s dev Blog | let's dev supports runners at the 7th KIT Championship

Corporate

let's dev supports runners at the 7th KIT Championship

by Karl

2019-07-05

Read more
let’s dev Blog | Apple WWDC 2019: These are the highlights of the keynote

Technical

Apple WWDC 2019: These are the highlights of the keynote

by Nicolas

2019-06-05

Read more
let’s dev Blog | App Builders 2019

Technical

App Builders 2019

by Nicolas

2019-05-23

Read more
let’s dev Blog | Official opening of the Consolidation and Expansion Center (FUX)

Corporate

Official opening of the Consolidation and Expansion Center (FUX)

by Helena

2019-04-15

Read more
let’s dev Blog | Delegation from Nottingham to visit the Alter Schlachthof in Karlsruhe

Corporate

Delegation from Nottingham to visit the Alter Schlachthof in Karlsruhe

by Helena

2019-04-14

Read more
let’s dev Blog | The time has come: We are moving!

Corporate

The time has come: We are moving!

by Helena

2019-03-26

Read more
let’s dev Blog | Automated testing of C++ code with frameworks - part 1

Technical

Automated testing of C++ code with frameworks - part 1

by Arne

2019-02-20

Read more
let’s dev Blog | The app in the Google Play Store

Technical

The app in the Google Play Store

by Elisa

2019-01-24

Read more
let’s dev Blog | „UX Day“ 2018

Corporate

„UX Day“ 2018

by Aileen

2018-12-17

Read more
let’s dev Blog | let's dev supports SG Siemens volleyball players from Karlsruhe

Corporate

let's dev supports SG Siemens volleyball players from Karlsruhe

by Helena

2018-12-04

Read more
let’s dev Blog | SMEs shape digitalization - SME Conference 2018

Corporate

SMEs shape digitalization - SME Conference 2018

by Helena

2018-11-12

Read more
let’s dev Blog | Apple Wallet

Technical

Apple Wallet

by Maik

2018-10-26

Read more
let’s dev Blog | „Mensch und Computer“ 2018

Corporate

„Mensch und Computer“ 2018

by Judith

2018-09-24

Read more
let’s dev Blog | State Design Pattern in Android

Technical

State Design Pattern in Android

by Thomas

2018-09-17

Read more
let’s dev Blog | let's dev is an authorized consulting company in the „go-digital“ funding program

Corporate

let's dev is an authorized consulting company in the „go-digital“ funding program

by Helena

2018-09-01

Read more
let’s dev Blog | App Design & Development Conference 2018

Corporate

App Design & Development Conference 2018

by Helena

2018-08-14

Read more
let’s dev Blog | iOS 12: The top new features at a glance

Technical

iOS 12: The top new features at a glance

by Nicolas

2018-07-17

Read more
let’s dev Blog | let's dev at CEBIT

Corporate

let's dev at CEBIT

by Karl

2018-06-11

Read more
let’s dev Blog | Introduction to User Interface (UI) Testing with Espresso

Technical

Introduction to User Interface (UI) Testing with Espresso

by Raphael

2018-06-07

Read more
let’s dev Blog | The app in the Apple App Store: what information is needed?

Technical

The app in the Apple App Store: what information is needed?

by Aileen

2018-04-27

Read more
let’s dev Blog | Smart Pointer in C++

Technical

Smart Pointer in C++

by Matthias

2018-04-01

Read more
let’s dev Blog | User interface design for iPhone X: all innovations at a glance

Technical

User interface design for iPhone X: all innovations at a glance

by Helena

2018-02-07

Read more
let’s dev Blog | WebVR - Virtual Reality Experience in the Browser with the A-Frame Framework

Technical

WebVR - Virtual Reality Experience in the Browser with the A-Frame Framework

by Judith

2018-01-10

Read more
let’s dev Blog | Deutsche Bahn Open Data Hackathon

Corporate

Deutsche Bahn Open Data Hackathon

by Karl

2015-03-31

Read more
let’s dev Blog | Blur effects under iOS 7

Technical

Blur effects under iOS 7

by Katja

2014-04-24

Read more
let’s dev Blog | Beyond App Store - iOS application distribution

Technical

Beyond App Store - iOS application distribution

by Karl

2012-08-27

Read more
let’s dev Blog | Front-end architecture - Model View Presenter and Message Bus

Technical

Front-end architecture - Model View Presenter and Message Bus

by Karl

2011-03-08

Read more