Mocking with GoogleTest (gtest)
Good Unit Testing with C++ (Part II)
Mocking with GoogleTest (gtest)
Good Unit Testing with C++ (Part II)
In a previous post I introduced the basics of testing with gtest. Here, we will look at mocking, a powerful feature for many use-cases.
Mocking — as the name suggests — describes mocking out certain functionality to simplify unit testing: prime examples are expensive, hard-to-test functions, such as database access, functions involving sleeping, waiting for user input, etc. Instead of putting unreasonable work into the unit tests, we simply replace (mock) the function in question. This also helps with encapsulation and allows “true” unit tests, instead of integration tests.

Image by vectorjuice on Freepik
Introductory Example
We will use a similar project setup to the previous post, using Bazel as build system — but please feel free to use anything you prefer:
BUILD
cc_library(
name = "gtest_example",
srcs = ["gtest_example.cc"],
hdrs = ["gtest_example.h"],
visibility = ["//visibility:public"],
deps = [
"@com_github_google_glog//:glog",
],
)
cc_test(
name = "gtest_example_test",
srcs = ["gtest_example_test.cc"],
deps = [
":gtest_example",
"@com_google_googletest//:gtest_main",
],
)
gtest_exampe.h
#pragma once
class ExampleClass {
public:
void mock_op();
private:
void foo();
};
gtest_example.cc
#include "gtest_samples/gtest_example.h"
#include <chrono>
#include <thread>
#include <glog/logging.h>
void ExampleClass::mock_op() { foo(); }
void ExampleClass::foo() {
LOG(INFO) << "Calling foo ...";
std::this_thread::sleep_for(std::chrono::seconds(10));
LOG(INFO) << "... calling foo done.";
}
ExampleClass defines a public function mock_op(), which internally calls the private function foo(). For a rough first look, we assume this function is “problematic”: in it, we sleep for 10s before returning, which we do not want to do in a unit test → we want to mock it.
But, to begin, here is the conventional unit test:
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
TEST(ExampleClassTest, TestMockOp) {
ExampleClass example = ExampleClass();
example.mock_op();
}
Mock Function
Now, to mock foo(), we use the macro MOCK_METHOD in a class inheriting from ExampleClass: this will make gtest overwrite foo of ExampleClass, and whenever we call mock_op of the child class, we will call this patched function (which — for now — does nothing):
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class ExampleClassMocked : public ExampleClass {
public:
MOCK_METHOD(void, foo, (), (override));
};
TEST(ExampleClassTest, TestMockOp) {
ExampleClassMocked example = ExampleClassMocked();
example.mock_op();
}
To enable these changes, we need to make foo of the base class virtual, and thus also declare a virtual destructor:
#pragma once
class ExampleClass {
public:
virtual ~ExampleClass(){};
void mock_op();
private:
virtual void foo();
};
When running this, we see that now the unit test finishes instantly, instead of sleeping for 10s. Congratulations, you mocked your first function!
Customizing the Mocked Function
In this section we’ll put some more flavour in the mix, and have a look at how to test the mocked function is called correctly, as well as modifying its behaviour.
Check Function is Called Appropriately
Checking whether the mocked function was indeed called can be done via EXPECT_CALL. This is very common, as these kind of unit tests often fully test the complete interface of a class and its interaction with others — and we want to make sure the appropriate function(s) is (are) called. Optionally, we can specify how often we expect a function to be called:
TEST(ExampleClassTest, TestMockOp) {
ExampleClassMocked example = ExampleClassMocked();
EXPECT_CALL(example, foo).Times(1);
example.mock_op();
}
We can further check, if a function was called with the right arguments. For this, we extend foo to expect an argument:
gtest_example.cc:
#include "gtest_samples/gtest_example.h"
#include <chrono>
#include <thread>
#include <glog/logging.h>
void ExampleClass::mock_op() { foo(10); }
void ExampleClass::foo(int x) {
LOG(INFO) << "Calling foo with ..." << x;
std::this_thread::sleep_for(std::chrono::seconds(10));
LOG(INFO) << "... calling foo done.";
}
gtest_example_test.cc:
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class ExampleClassMocked : public ExampleClass {
public:
MOCK_METHOD(void, foo, (int x), (override));
};
TEST(ExampleClassTest, TestMockOp) {
ExampleClassMocked example = ExampleClassMocked();
EXPECT_CALL(example, foo(10)).Times(1);
example.mock_op();
}
Return Values from Mocked Function
In addition, we can modify the behaviour of a mocked function. Let’s slightly change our setup: we want to unit test mock_op, which now returns a value — namely the return of foo. To skip the sleep but still achieve the right result, we tell mocked foo to simply return the expected:
gtest_example.cc:
#include "gtest_samples/gtest_example.h"
#include <chrono>
#include <thread>
#include <glog/logging.h>
int ExampleClass::mock_op() { return foo(); }
int ExampleClass::foo() {
LOG(INFO) << "Calling foo ...";
std::this_thread::sleep_for(std::chrono::seconds(10));
LOG(INFO) << "... calling foo done.";
return 10;
}
gtest_example_test.cc:
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class ExampleClassMocked : public ExampleClass {
public:
MOCK_METHOD(int, foo, (), (override));
};
TEST(ExampleClassTest, TestMockOp) {
ExampleClassMocked example = ExampleClassMocked();
EXPECT_CALL(example, foo()).Times(1).WillOnce(::testing::Return(10));
EXPECT_EQ(example.mock_op(), 10);
}
If we want the example to be a bit fancier / more realistic, let’s change the code s.t. foo takes a parameter as input and returns that — correspondingly we modify the expected return in the unit test:
gtest_example.cc:
#include "gtest_samples/gtest_example.h"
#include <chrono>
#include <thread>
#include <glog/logging.h>
int ExampleClass::mock_op(int x) { return foo(x); }
int ExampleClass::foo(int x) {
LOG(INFO) << "Calling foo with ..." << x;
std::this_thread::sleep_for(std::chrono::seconds(10));
LOG(INFO) << "... calling foo done.";
return x;
}
gtest_example_test.cc:
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class ExampleClassMocked : public ExampleClass {
public:
MOCK_METHOD(int, foo, (int x), (override));
};
TEST(ExampleClassTest, TestMockOp) {
ExampleClassMocked example = ExampleClassMocked();
EXPECT_CALL(example, foo(11)).Times(1).WillOnce(::testing::ReturnArg<0>());
EXPECT_EQ(example.mock_op(11), 11);
}
Refactoring Example to Professional Software Level
Our above example hopefully helped introducing Mocking, but it is bad testing style, and also would not be used in this form in professional software projects.
Unit testing should only cover public interfaces of classes — we test the class upholds their end of the contract, and leave the internal implementation hidden away. Thus, we would not mock a private function and test that it is called correctly (as a side comment, note the little “curiosity” seen above: changing the visibility of a function in an inherited class actually is proper C++).
In reality, we would potentially mock a public function of another class — which comes with some other interesting challenges / consequences, covering which is the goal of this section.
Thus, let’s first refactor our project to reflect a “better” design (“better” interpreted as: more likely to be seen in a professional project — for our toy example it does not really make sense to separate the classes, but as mentioned above we would not write such unit tests in practise):
gtest_example.h
#pragma once
class ExampleClassB {
public:
int foo(int x);
};
class ExampleClassA {
public:
ExampleClassA(const ExampleClassB& example_class);
int mock_op(int x);
private:
ExampleClassB example_class_b_;
};
gtest_example.cc
#include "gtest_samples/gtest_example.h"
#include <chrono>
#include <thread>
#include <glog/logging.h>
ExampleClassA::ExampleClassA(const ExampleClassB& example_class_b)
: example_class_b_(example_class_b){};
int ExampleClassA::mock_op(int x) { return example_class_b_.foo(x); }
int ExampleClassB::foo(int x) {
LOG(INFO) << "Calling foo with ..." << x;
std::this_thread::sleep_for(std::chrono::seconds(10));
LOG(INFO) << "... calling foo done.";
return x;
}
This is a frequent pattern: via composition ExampleClassA manages an instance of ExampleClassB, and inside mock_op calls its public method foo.
This could then for example be used as such from a main file:
#include <glog/logging.h>
#include "gtest_samples/gtest_example.h"
int main() {
ExampleClassA example_class_a = ExampleClassA(ExampleClassB());
LOG(INFO) << example_class_a.mock_op(10);
}
Now, we again want to mock foo. As a first try, we might simply do this:
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class ExampleClassBMocked : public ExampleClassB {
public:
MOCK_METHOD(int, foo, (int x), (override));
};
TEST(ExampleClassTest, TestMockOp) {
ExampleClassBMocked example_class_b = ExampleClassBMocked();
ExampleClassA example_class_a = ExampleClassA(example_class_b);
EXPECT_CALL(example_class_b, foo(11))
.Times(1)
.WillOnce(::testing::ReturnArg<0>());
EXPECT_EQ(example_class_a.mock_op(11), 11);
}
However, due to slicing in C++, this will actually call the base class’ method, i.e. ExampleClassB::foo! The reason is, that when doing the assignment example_class_b_(example_class_b) a copy is made, and the object we end up with is of type ExampleClassB. This pattern in general is nasty and can lead to some weird and unexpected behaviour, and thus should be avoided.
To solve this issue, we change the attribute example_class_b_ to hold a pointer — thus circumventing the problem of slicing:
#pragma once
class ExampleClassB {
public:
virtual ~ExampleClassB(){};
virtual int foo(int x);
};
class ExampleClassA {
public:
ExampleClassA(ExampleClassB* example_class);
int mock_op(int x);
private:
ExampleClassB* example_class_b_;
};
#include "gtest_samples/gtest_example.h"
#include <chrono>
#include <thread>
#include <glog/logging.h>
ExampleClassA::ExampleClassA(ExampleClassB* example_class_b)
: example_class_b_(example_class_b){};
int ExampleClassA::mock_op(int x) { return example_class_b_->foo(x); }
int ExampleClassB::foo(int x) {
LOG(INFO) << "Calling foo with ..." << x;
std::this_thread::sleep_for(std::chrono::seconds(10));
LOG(INFO) << "... calling foo done.";
return x;
}
#include "gtest_samples/gtest_example.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class ExampleClassBMocked : public ExampleClassB {
public:
MOCK_METHOD(int, foo, (int x), (override));
};
TEST(ExampleClassTest, TestMockOp) {
ExampleClassBMocked example_class_b = ExampleClassBMocked();
ExampleClassA example_class_a = ExampleClassA(&example_class_b);
EXPECT_CALL(example_class_b, foo(11))
.Times(1)
.WillOnce(::testing::ReturnArg<0>());
EXPECT_EQ(example_class_a.mock_op(11), 11);
}
Outlook
This concludes this introduction to mocking with gtest. As a departing comment, I want to point out that frequently [ExampleClassB](https://en.cppreference.com/w/cpp/language/abstract_class) will be an abstract base class — this is often due to the needs of the selected software design, and further helps organize the relationship of the used classes.
I hope, you enjoyed this post, and if you did — to see you back for more.
메타데이터
- post_id
- 6dde5230e7aa
- slug
- mocking-with-googletest-gtest-6dde5230e7aa
- url
- https://levelup.gitconnected.com/mocking-with-googletest-gtest-6dde5230e7aa
- canonical_url
- https://levelup.gitconnected.com/mocking-with-googletest-gtest-6dde5230e7aa
- author_url
- https://medium.com/@hrmnmichaels
- status
- ok
- fetched_at
- 2026-06-29 22:44:20