【发布时间】:2013-01-06 19:59:41
【问题描述】:
我在安排代码以使其易于测试时遇到问题。我的代码中有 2 个主要模块:缓存生成器和修改器生成器,两者的复杂程度大致相同。修饰符builder用于缓存生成器的子对象的方法之一。
我已经拥有完整的测试套件,其中涵盖了修饰符生成器的功能。我想添加涵盖缓存生成器所有功能的测试,但为了显着降低这些测试的复杂性,我需要用一些存根替换修饰符生成器,它根据我传递给它的参数返回预定义的“罐头数据”。
我的实际问题在于选择用存根替换真实修饰符构建器的方式,这在代码方面看起来不错,并且仍然便于测试。看看下面的代码:
来自GitHub的代码:
cacheGenerator / generator.py:
class CacheGenerator:
def __init__(self, logger):
...
self._converter = Converter(logger)
def run(self, dataHandler):
...
data = self._converter.convert(data)
cacheGenerator/converter.py:
class Converter:
...
def convert(self, data):
...
self._buildModifiers(data)
def _buildModifiers(self, data):
...
builder = ModifierBuilder(data['expressions'], self._logger)
...
modifiers, buildStatus = builder.buildEffect(...)
用存根替换修饰符生成器的方法是什么?我想至少存在以下几个变体:
- 对代码的更改:在转换器的 init() 中实例化修饰符生成器并将其实例分配为对象属性。对于测试 - 创建真正转换器的子类,覆盖 init(),我们用存根替换真正的修饰符生成器,然后子类化缓存生成器,以类似的方式用子类替换真正的转换器。但是,这种方法需要修改修饰符生成器:我需要从 init() 方法中拆分数据加载,这是不可取的
- 与 1) 类似,但将与修改器生成器一起使用的 Converter()._buildModifiers() 方法的部分内容移动到单独的方法中,以使它们易于被覆盖
- 类似于 1),但在清洁器的 init() 中仅指定修饰符生成器类(而非实例)。这使我们可以保持修饰符生成器不变。
- 从缓存生成器的最顶部传递修饰符构建器类(以便我们需要替换以进行测试的类可以通过缓存生成器实例化来控制)
- 还有其他变种吗?喜欢一些进口魔法?
1-4 中的一些变体看起来可以接受,但理想情况下,我希望代码尽可能接近(与原始代码),因此我正在研究存根子对象的替代方法。
【问题讨论】:
标签: python unit-testing python-3.x