GMock的接口包装器类的继承

问题描述

我有几个班级,都属于一个服务。该服务正在为其他模块提供不同的服务。

所以我有 ServiceModuleA.h:

#include "ServiceModuleCommon.h"
namespace na{

    class ModuleAInfo
    {
      std::string wVara;
    };
}
class ServiceModuleA : public ServiceCommon
{
public:
    ServiceModuleA();
    ~ServiceModuleA();

    bool ReadListFunction(std::vector<na::ModuleAInfo>& info);

};

ServiceModuleB.h:

#include "ServiceModuleCommon.h"
namespace nb{

    class ModuleBInfo
    {
      std::string wVarB;
    };
}
class ServiceModuleB : public ServiceCommon
{
public:
    ServiceModuleB();
    ~ServiceModuleB();

    bool ReadListFunction(std::vector<nb::ModuleBInfo>& info);

};

ServiceModuleCommon.h:

namespace nCommon{

    typedef struct Function : base SomeXmlStuff
    {
      std::string wVarXYZ;
      Function();
      void Set(std::string name,std::string value) override;
      void Set(std::string number,str::string parent) override;
    }Function_t;
}
class ServiceModuleCommon
{
public:
    ServiceModuleCommon();
    ~ServiceModuleCommon();

    bool ReadSomeLists(std::vector<int>& wIntvar);  
};

现在我需要创建一些模拟。我知道以下事实:虚拟的没有实现。因此,我使用接口类来包装所有内容

ServiceModuleAMock.h:

#include "ServiceModuleCommonMock.h"
#include "gmock/gmock.h"
namespace na{

    class ModuleAInfo_Fake
    {
      std::string wVara;
    };
}
class IServiceModuleAMock
{ 
   public:
       virtual bool ReadListFunction(std::vector<na::ModuleAInfo_Fake>& info);
};
class ServiceModuleAMock : public IServiceModuleAMock,public ServiceCommonMock
{
public:
    ServiceModuleAMock();
    ~ServiceModuleAMock();

    MOCK_METHOD(bool,ReadListFunction,(std::vector<na::ModuleAInfo_Fake>& info));

};

inline bool ReadListFunction(std::vector<na::ModuleAInfo_Fake>& info)
{
     return ReadListFunction(info);
}

ServiceModuleBMock.h:

#include "ServiceModuleCommonMock.h"
#include "gmock/gmock.h"
namespace nb{

    class ModuleBInfo_Fake
    {
      std::string wVarB;
    };
}
class IServiceModuleBMock : public IServiceCommonMock
{
     public:
       virtual bool ReadListFunction(std::vector<nb::ModuleBInfo_Fake>& info);
};

class ServiceModuleBMock : public IServiceModuleBMock 
{
public:
    ServiceModuleBMock();
    ~ServiceModuleBMock();

    MOCK_METHOD(bool,(std::vector<nb::ModuleBInfo_Fake>& info));

};

inline bool ReadListFunction(std::vector<nb::ModuleBInfo_Fake>& info)
{
     return ReadListFunction(info);
}

ServiceModuleCommonMock.h:

#include "gmock/gmock.h"
namespace nCommon{

    typedef struct FunctionFake : base SomeXmlStuffFake //  exists somewhere I created it
    {
      std::string wVarXYZ;
      FunctionFake();
      void Set(std::string name,str::string parent) override;
    }Function_tFake;
}
class IServiceModuleCommonMock
{
   public:
   virtual bool ReadSomeLists(std::vector<int>& wintvar);
};
class ServiceModuleCommonMock : public IServiceModuleCommonMock
{
public:
    ServiceModuleCommonMock();
    ~ServiceModuleCommonMock();

    MOCK_METHOD(bool,ReadSomeLists,(std::vector<int>& wIntvar));

};

inline bool ReadSomeLists(std::vector<int>& wintvar)
{
     return ReadSomeLists(wintvar);
}

请注意,我已经尝试了两种不同的继承“ Common”类的方式。 如果我编译这些标头(我只创建包含标头的cpp文件,并实现一个空的析构函数和构造函数),则它们全部都是自己编译的。 如果我要编译文件进行测试:

Service.cpp

#ifdef _UNITTEST
#include "ServiceModuleAMock.h"
#define ServiceModuleA ServiceModuleAMock
#include "ServiceModuleBMock.h"
#define ServiceModuleB ServiceModuleBMock
#include "ServiceModuleCommonMock.h"
#define ServiceModuleCommon ServiceModuleCommonMock
#else
#include "ServiceModuleA.h"
#include "ServiceModuleB.h"
#include "ServiceModuleCommon.h"
#endif

// Continues with some stuff classes usually do and is compiling if _UNITTEST is turned off

如果设置了_UNITTEST,我最终还是会遇到多个但相同的错误

Error   C2039   'FunctionFake': is not a member of 'testing::internal'  
E0135 namespace "testing::internal" has no member "FunctionFake"  ServiceModuleA
E0135 namespace "testing::internal" has no member "FunctionFake"  ServiceModuleB
Error   C2059   Syntax error: ')'   ServiceModuleA
Error   C2059   Syntax error: ')'   ServiceModuleB

等等等。如果我双击E0135,我最终会到达我的MOCK_METHOD(...)

由于FunctionFake在此公共支持程序类中,所以我想知道继承是否存在问题。 但是,我最初的“未模拟”类都没有使用FunctionFake。我还确保所有内容的结构都与原始文件中的相同,只是伪造了那些微型struct类并模拟了主要类。

如果有帮助,我可以使用Microsoft Visual Studio 2017 + GoogleTest版本1.10.0

预先感谢您耐心阅读这篇文章。 让我知道是否弄乱了一些代码片段。

// =================更新============== //

我能够使其编译,但是我不明白为什么。 在Service.h和ServiceModuleFunctionManager.h中,我有一个

#define Function FunctionFake

而Service.h和ServiceModuleFunctionManager.h没有假货或假货。我认为可以,因为它是在Common模块中定义的。

因此继承很好,但可以改进,此定义有问题...

#ifdef _UNITTEST
... code having FunctionFake...
#else
... code having Function...
#end 

为我工作。

ProTip:如果您遇到奇怪的误导性错误,并且每个部分都在自行编译,则错误可能确实出在您未独立编译的包含文件之一或唯一未编译的文件中。

解决方法

IMO使用_UNITTEST之类的东西应被视为不良做法,因为生产代码不会意识到测试。

我没有看到完整的图片,因为没有提供ServiceCommon的定义,但是它将是带有虚拟析构函数和纯虚拟方法的纯抽象类。用非虚拟方法模拟所有东西,定义和其他破解和变通办法似乎都行得通,但是您在生产中使用的代码不同,而在测试中使用的代码也不同(意思是:不同的绑定和可能的不同行为!),因此您测试未测试实际代码。

为什么不使用适当的抽象基类等?