Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模仿整个图书馆_C++_Mocking_Boost Asio_Googletest_Googlemock - Fatal编程技术网

C++ 模仿整个图书馆

C++ 模仿整个图书馆,c++,mocking,boost-asio,googletest,googlemock,C++,Mocking,Boost Asio,Googletest,Googlemock,我正在开发使用boost::asio的代码。为了测试它,我需要模拟这个库中的一组类。我正在使用GoogleMock,它允许模拟虚拟方法。通常(而且繁琐)的过程是为我需要使用的每个类编写一个接口 另一方面,Google Mock Cookbook描述了一种模拟非虚拟方法的替代方法:使用模板。在我的例子中,问题是我可能需要同时模拟几个类(因此直接使用模板是行不通的)。所以我想:为什么不使用两个级别的模板呢?我提出了以下解决方案: // Classes to be mocked. class Rea

我正在开发使用
boost::asio
的代码。为了测试它,我需要模拟这个库中的一组类。我正在使用GoogleMock,它允许模拟虚拟方法。通常(而且繁琐)的过程是为我需要使用的每个类编写一个接口

另一方面,Google Mock Cookbook描述了一种模拟非虚拟方法的替代方法:使用模板。在我的例子中,问题是我可能需要同时模拟几个类(因此直接使用模板是行不通的)。所以我想:为什么不使用两个级别的模板呢?我提出了以下解决方案:

// Classes to be mocked.

class RealA
{
public:
    void a() { cout << "RealA::a()" << endl; };
};

class RealB
{
public:
    void b() { cout << "RealB::b()" << endl; };
};

// Mock classes.

class MockA
{
public:
    void a() { cout << "MockA::a()" << endl; };
};

class MockB
{
public:
    void b() { cout << "MockB::b()" << endl; };
};

template<class ABFactory>
class Program
{
public:
    void setFactory(ABFactory* factory) { factory = factory; }
    void useA() { typename ABFactory::A* a = factory->createA(); a->a(); delete a; }
    void useB() { typename ABFactory::B b; b.b(); }

private:
    ABFactory* factory;
};


template<class ParamA, class ParamB>
class TABFactory
{
public:
    typedef ParamA A;
    typedef ParamB B;
    A* createA() { return new A; };
    B* createB() { return new B; };
};

typedef TABFactory<RealA, RealB> RealABFactory;
typedef TABFactory<MockA, MockB> MockABFactory;
//要模拟的类。
雷亚尔级
{
公众:

void a(){cout这是

另见

我使用cog为事件列表生成处理程序,处理程序代码非常通用,我不需要执行特殊情况,但我仍然需要编写所有函数,因此我所做的是将事件保存在.py文件的列表中,并将代码保存在python函数中生成处理程序的样板文件中。因此,我能够忠实于

显然,为了使用工具链,您必须将cog添加到生成文件的预构建中

编辑作为向类中添加样板文件所需的代码生成设计示例,我将执行以下操作:

霉菌变性 然后在标题中:

IfaceA.h 莫卡

还有,如果考虑到Python添加到C++源,那就是“污染”或者“美化”,这主要是一个品味和风格的问题。我认为COG为C++中缺少的模板式元编程提供了补充,给程序员提供了代码整洁和可读性。但是我并不期望每个人都能做到。同意

对我来说,这种方法背后的整个体系结构设计原则是不要重复你自己。当我们必须在多个地方手动编码一个方法时,就会发生错误。让计算机自动化它可以自动化的东西,并对不能只编码一次的东西进行编码。作为一种副作用,它将使你的编码更加有趣,无论是写还是写把它整理一下,以后再读


希望这有助于

通过Python内嵌生成C++代码的能力看起来很有趣,但我没能看到它如何解决这个特定的问题。你能举个例子吗?它也会污染Python的C++代码(不是每个C++程序员都熟悉的)非常有趣的问题。我同意你关于污染与美化的观点(我喜欢Python),只是我认为C++代码应该保持“纯”(特别是当非Python程序员必须读/(re))时。编写它。与创建一组库接口和使用Google Mock相比,您认为这种方法如何?@brunonery,这种方法是关于扩展对大量应用于许多模拟类的修改的控制;只需添加对代码生成的修改并重新生成。而且更重要的是,这不应该代表蕾丝作为谷歌模拟的一个模拟框架,你仍然需要添加嘲讽代码。在我的例子中,模拟的主体有一个虚拟宏,你必须在那里添加模拟工具。@布鲁尼,同样,我也认为添加代码生成工具不是一个标准的C++,这是一种不完美,但是我意识到,坚持纯C++。对于我来说,这一原则比任何语言纯度范式都要高
Program<RealABFactory> p;
p.useA();
p.useB();
Program<MockABFactory> t;
t.useA();
t.useB();
import cog
ClassesToMock = [ [ 'IfaceA' , 'classA' , 'mockA' , ['void doSomething(int foo)' , 'int getSomething()'] 
                 , [ 'IfaceB', 'classB' , 'mockB' , ['static classA& getInstance()'] ]

def addInterfaces( myStructure ):
   for classItem in myStructure:
      cog.outl('class %s { ' % classItem[0] )
      for methodDecl in classItem[3]:
         cog.outl(' virtual %s = 0;' %methodDecl )
      cog.outl(' } ')

#implement your real classes normally

def addMocks( myStructure ):
   for classItem in myStructure:
      cog.outl('class %s : public %s { ' % classItem[2] % classItem[0] )
      for methodDecl in classItem[3]:
         cog.outl(' %s {' %methodDecl )
         cog.outl(' MOCK_STUFF_MACRO ')
         cog.outl(' } ')
      cog.outl(' } ')
/*[[[cog
import cog
import myCodeGeneration

myCodeGeneration.addInterfaces( [ [ 'IfaceA' , 'classA' , 'mockA' , ['void doSomething(int foo)' , 'int getSomething()'] ] )
]]]*/

//your code will be generated here

//[[[end]]]
/*[[[cog
import cog
import myCodeGeneration

myCodeGeneration.addMocks( [ [ 'IfaceA' , 'classA' , 'mockA' , ['void doSomething(int foo)' , 'int getSomething()'] ] )
]]]*/

//your code will be generated here

//[[[end]]]