【问题标题】:Practical example for Dependency Injection and mocking with Googlemock使用 Googlemock 进行依赖注入和模拟的实用示例
【发布时间】:2021-03-13 16:08:50
【问题描述】:

我正在寻找一个简单的完整剪切和粘贴示例,用于使用 Googlemock 进行依赖注入和模拟。我发现了几个关于代码 sn-ps 问题的理论讨论,这些讨论解释了它是如何工作的,但无法找到一个完整的运行示例来剪切和粘贴并尝试。有货吗?

【问题讨论】:

    标签: c++ unit-testing dependency-injection googlemock


    【解决方案1】:

    为了了解它如何与 Googlemock 一起工作,我制作了这个完整的示例,我想与其他初学者分享该主题。根据其他问答理论背景假设。我在 Debian Bullseye 系统上运行它。

    在一个虚构的库中有一个类Mylib,该方法只返回123。在测试中,它被模拟返回456。真实类和模拟类都继承自接口类。这确保了由注入器(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.
    

    【讨论】:

      猜你喜欢
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多