Define GMock unit-testing framework

A key component of software development is unit testing, which enables programmers to confirm that individual code units or components are valid. Several frameworks have been created to help with efficient C++ unit testing; one such strong tool is Google Mock or GMock. Mock-based unit testing is made easier and more versatile with GMock, which is an addition to the Google Test framework.

Understanding GMock

Google created the C++ mocking framework known as GMock or Google Mock. Although it is designed to integrate easily with the Google Test framework, the library may also be used alone. Making mock objects for unit testing is the primary objective of GMock, which enables developers to isolate and test individual components from the rest of the program.

Basic usage of GMock

Gmock is particularly useful when isolating a component from its dependencies in unit testing. We can define mock classes with expectations and then confirm whether the expectations are fulfilled during testing. Let’s walk through the basic steps of using GMock in a unit test:

Include GMock headers

For using Gmock, necessary headers must be included in the test file. The primary headers used are <gmock/gmock.h> and <gtest/gtest.h>.

#include <gmock/gmock.h>
#include <gtest/gtest.h>
Headers

Define mock class

It is considered best practice to test code while using interfaces because, with this, we can provide mock interface implementations. So, we can create a mock class that inherits from the class or interface we want to mock. We can define mock methods in the mock class by using the MOCK_METHOD macro. The signature of these methods must match the original methods in the actual class.

class MockClass {
public:
MOCK_METHOD(returnType, MockMethod, (parameter1, parameter2));
};
Syntax of the MockClass in c++

MOCK_METHOD is a macro provided by GMock to declare a mock method. The parameters of this macro are as follows:

  • returnType: This is the return type of the mock method (MockMethod).

  • MockMethod: This is the name of the mock method.

  • (parameter1, parameter2): This is the parameter list of the mock method. In this case, MockMethod takes two parameters: an integer (parameter1) and a double (parameter2).

Set expectations

The test function must create an instance of the mock class object. Next, establish expectations for the mock methods using the EXPECT_CALL macro. We may use a variety of actions to describe the behavior and provide the arguments we anticipate the method to be called with.

using ::testing::Return;
TEST(MyTest, TestScenario) {
MockClass mockObj;
EXPECT_CALL(mockObj, MockMethod(42, _))
.WillOnce(Return(100));
}
Expectation setting

TEST(MyTest, TestScenario) is a macro that defines a test fixture named MyTest with a test named TestScenario. Test fixtures are used to group related tests together. In this case, MyTest is the name of the test fixture and TestScenario is the name of the specific test within that fixture.

EXPECT_CALL(mockObj, MockMethod(42, _)) is a line that sets an expectation on the MockMethod of the mockObj. It specifies that the MockMethod should be called with the arguments 42 and any value (indicated by _). This expectation is set up to occur once. And .WillOnce(Return(100)) specifies what should happen when the expectation is met. In this case, it says that when MockMethod is called with the specified arguments, it should return 100.

After all this, we can write our test code to interact with the mockObj.

Run the test

Lastly, execute the test using a test runner, like the one offered by Google Test. The test runner will create the mock object, run the test code, and confirm that the mock methods’ expectations are fulfilled.

Example

In the code example below, we perform a unit test for the Calculator C++ class, which performs an add operation. It tests using the GMock and GTest frameworks.

test.cpp
calculator.cpp
calculator.h
// calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator {
public:
virtual int Add(int a, int b);
};
#endif // CALCULATOR_H

Code explanation

  • Lines 1–5: These lines include the required headers.

  • Lines 8–11: These lines declare a mock method, Add, which overrides the Add method of the Calculator class. It takes two integer parameters a and b of integer type, and returns an integer.

  • Lines 13: It defines a test case, namely AddTest inside the CalculatorTest test suite.

  • Line 15: It declares an instance of MockCalculator class for testing.

  • Lines 17–18: This line sets an expectation for the Add method. It expects that when Add is called with arguments 2 and 3, it will return 5.

  • Line 20: It calls the Add method with arguments 2 and 3.

  • Lines 22: It verifies the result with the expected value.

Key features of GMock

We'll discuss some key features of GMock below:

Mock objects

GMock is a tool that lets developers construct mock objects—some other objects that behave like actual objects but are managed by test code. This is very helpful when testing a class that depends on outside elements like databases, network connections, or third-party libraries.

Behavior verification

Verifying the behavior of fake objects is one of GMock’s primary functionalities. GMock allows developers to specify how a fake object should be called during a test, and it will determine if developers’ expectations are fulfilled.

Flexible matchers

When configuring mock object behavior, GMock offers various ways to indicate the expected arguments. Because of this flexibility, developers may specify exact expectations for function calls.

Nice mocks vs. strict mocks

GMock supports both “strict” and “nice” mocks. While strict mocks fail the test if unexpected calls happen, nice mocks overlook them. This allows users to select the strictness required for a certain case.

Parameterized tests

The parameterized test capability of Google Test may be easily integrated with GMock, enabling developers to create parameterized tests for various input data types.

Advanced GMock usage

GMock provides advanced features for handling more complex scenarios, such as:

Mocking non-virtual methods

When mocking non-virtual methods, GMock provides a solution using template specialization. By building a template class inherited from the original class, we may efficiently override and mimic non-virtual functions.

Partial mocks

With GMock’s partial mocks, you may mock only a portion of an actual object’s methods while keeping the remainder of its behavior original. This is especially useful if you want to concentrate on testing one method while keeping the real implementation of other methods in the same class.

Advanced matchers

GMock offers a large collection of sophisticated matches to help define exact expectations for the arguments supplied to mocked methods. These matches help developers create expectations for user-defined types and apply unique criteria for more intricate comparisons. This sophisticated matching capability improves GMock’s expressiveness and adaptability, enabling it to handle complex testing scenarios easily.

Conclusion

In conclusion, GMock is a robust and adaptable C++ mocking framework that makes building unit tests for large, complicated codebases easier. Developers may ensure that different parts of their program work as intended by making fake objects, establishing expectations, and confirming behavior. For creating solid and dependable unit tests in C++ applications, GMock is an indispensable tool that can be used independently or in combination with Google Test.

Free Resources

Copyright ©2024 Educative, Inc. All rights reserved