Mocking an entire library

折月煮酒 提交于 2019-12-04 07:51:45
lurscher

this is a perfect use case for python cog

see also this answer.

I've used cog to generate handlers for a list of events, the handler code is very generic and i don't need to do special cases but i still have to write all the functions, so what i did is keep the events in a list in a .py file and the code to generate the boilerplate of the handlers in a python function. so i'm able to be faithful to the DRY principle

obviously you'll had to add cog to the pre-build of your makefile in order to work with your toolchain

Edit as an example of the code generation design required for adding boilerplate to your classes, i would do something like:

myCodeGeneration.py

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(' } ')

then in your header:

IfaceA.h

/*[[[cog
import cog
import myCodeGeneration

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

//your code will be generated here

//[[[end]]]

mockA.h

/*[[[cog
import cog
import myCodeGeneration

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

//your code will be generated here

//[[[end]]]

Also, the issue if considering adding python to your c++ source is 'polluting' it or 'beautifying' it is largely a matter of taste and style. I consider that cog provides a complement to template style metaprogramming that is lacking in c++, giving the tools to the programmer to provide code tidiness and readability. But i don't expect everyone to agree

For me the whole architectural design principle behind this approach is Don't Repeat Yourself. errors happen when we have to encode a method in several places manually. Let the computer automate what its automatable and encode things that cannot just once. As a side-effect, it will make your coding more enjoyable, both for writing it and reading it later.

hope this helps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!