依赖注入和使用 Googlemock 模拟的实际示例
Practical example for Dependency Injection and mocking with Googlemock
我正在寻找一个简单的完整剪切和粘贴示例,用于使用 Googlemock 进行依赖注入和模拟。我发现了一些关于该问题的理论讨论,其中的代码片段解释了它是如何工作的,但无法找到完整的 运行 示例来剪切和粘贴并尝试。有空的吗?
为了了解它如何与 Googlemock 一起工作,我制作了这个完整的示例,我想与其他初学者分享该主题。根据其他问答假设理论背景。我 运行 它在 Debian Bullseye 系统上。
在一个虚构的库中有一个 class Mylib
方法只是 returns 123
。在测试中它被模拟为 return 456
。真正的 class 和模拟 class 都是从接口 class 继承的。这确保了由注入器(TEST(..){..}
宏)注入到应用程序 Myapp
的不同对象具有相同的方法调用。这是示例:
~$ cat test_myapp.cpp
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <iostream>
class MylibInterface {
public:
virtual ~MylibInterface() {}
virtual int func() = 0;
};
class Mylib : public MylibInterface {
public:
virtual ~Mylib() {}
int func() override {
return 123;
}
};
class MylibMock : public MylibInterface {
public:
virtual ~MylibMock() {}
MOCK_METHOD(int, func, (), (override));
};
class Myapp {
// this pointer will be injected by the injector either with pointing
// to the real object or to the mock object. The interface ensures that both
// objects have the same method calls.
MylibInterface* m_mylib;
public:
Myapp(MylibInterface* mylib) : m_mylib(mylib) {}
bool func() {
int ret = m_mylib->func();
std::cout << "mylib.func returns: '" << ret << "'\n";
return true;
}
};
TEST(MylibTestSuite, mock_mylib_func)
// this test macro can be seen as the injector. It determins what object
// is injected to myapp.
{
using ::testing::Return;
// inject a real mylib object to myapp and exersize it
Mylib mylib;
Myapp myapp(&mylib);
std::cout << " real ";
EXPECT_TRUE(myapp.func());
// inject a mocked mylib object to myapp
MylibMock mylib_mock;
Myapp myapp_mock(&mylib_mock);
EXPECT_CALL(mylib_mock, func())
.WillOnce(Return(456));
// and exersize it
std::cout << "mocked ";
EXPECT_TRUE(myapp_mock.func());
}
int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
我编译它:
~$ /usr/bin/g++ -std=c++11 -pedantic-errors -Wall -o test_myapp.a -I$BUILD_DIR/googletest-src/googletest/include -I$BUILD_DIR/googletest-src/googlemock/include test_myapp.cpp $BUILD_DIR/lib/libgtestd.a $BUILD_DIR/lib/libgmockd.a -lpthread
执行测试时应该如下所示:
~$ ./test_myapp.a
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MylibTestSuite
[ RUN ] MylibTestSuite.mock_mylib_func
real mylib.func returns: '123'
mocked mylib.func returns: '456'
[ OK ] MylibTestSuite.mock_mylib_func (0 ms)
[----------] 1 test from MylibTestSuite (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
我正在寻找一个简单的完整剪切和粘贴示例,用于使用 Googlemock 进行依赖注入和模拟。我发现了一些关于该问题的理论讨论,其中的代码片段解释了它是如何工作的,但无法找到完整的 运行 示例来剪切和粘贴并尝试。有空的吗?
为了了解它如何与 Googlemock 一起工作,我制作了这个完整的示例,我想与其他初学者分享该主题。根据其他问答假设理论背景。我 运行 它在 Debian Bullseye 系统上。
在一个虚构的库中有一个 class Mylib
方法只是 returns 123
。在测试中它被模拟为 return 456
。真正的 class 和模拟 class 都是从接口 class 继承的。这确保了由注入器(TEST(..){..}
宏)注入到应用程序 Myapp
的不同对象具有相同的方法调用。这是示例:
~$ cat test_myapp.cpp
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <iostream>
class MylibInterface {
public:
virtual ~MylibInterface() {}
virtual int func() = 0;
};
class Mylib : public MylibInterface {
public:
virtual ~Mylib() {}
int func() override {
return 123;
}
};
class MylibMock : public MylibInterface {
public:
virtual ~MylibMock() {}
MOCK_METHOD(int, func, (), (override));
};
class Myapp {
// this pointer will be injected by the injector either with pointing
// to the real object or to the mock object. The interface ensures that both
// objects have the same method calls.
MylibInterface* m_mylib;
public:
Myapp(MylibInterface* mylib) : m_mylib(mylib) {}
bool func() {
int ret = m_mylib->func();
std::cout << "mylib.func returns: '" << ret << "'\n";
return true;
}
};
TEST(MylibTestSuite, mock_mylib_func)
// this test macro can be seen as the injector. It determins what object
// is injected to myapp.
{
using ::testing::Return;
// inject a real mylib object to myapp and exersize it
Mylib mylib;
Myapp myapp(&mylib);
std::cout << " real ";
EXPECT_TRUE(myapp.func());
// inject a mocked mylib object to myapp
MylibMock mylib_mock;
Myapp myapp_mock(&mylib_mock);
EXPECT_CALL(mylib_mock, func())
.WillOnce(Return(456));
// and exersize it
std::cout << "mocked ";
EXPECT_TRUE(myapp_mock.func());
}
int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
我编译它:
~$ /usr/bin/g++ -std=c++11 -pedantic-errors -Wall -o test_myapp.a -I$BUILD_DIR/googletest-src/googletest/include -I$BUILD_DIR/googletest-src/googlemock/include test_myapp.cpp $BUILD_DIR/lib/libgtestd.a $BUILD_DIR/lib/libgmockd.a -lpthread
执行测试时应该如下所示:
~$ ./test_myapp.a
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MylibTestSuite
[ RUN ] MylibTestSuite.mock_mylib_func
real mylib.func returns: '123'
mocked mylib.func returns: '456'
[ OK ] MylibTestSuite.mock_mylib_func (0 ms)
[----------] 1 test from MylibTestSuite (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.