1

我正在编写一个小型模拟类来做一些测试。

但是这个类需要支持具有嵌套属性的想法。

这个例子应该提供一些关于这个问题的见解:

class Foo(object):

    def __init__(self):
        self.x = True

从上面的类,我们可以有:

f = Foo()
f.x

我知道我可以添加回退__getattr__的属性以避免出现 AttributeError,但是如果我需要这样的东西是有效的怎么办:

f = Foo()
f.x
f.x.y
f.x.y.z()

如果对象被调用,我知道要返回什么,f.x.y.z()但我只需要找到一种方法来实现z()它是有意义的。

4

2 回答 2

3

您可以通过在每个属性访问时返回“模拟任何东西”类的另一个实例来“模拟任何东西”(如果您想让.z()部分工作,它也必须是可调用的;-)。

例如:

class MockAny(object):

  # mock special methods by making them noops
  def __init__(self, *a, **k): pass

  # or returning fixed values
  def __len__(self): return 0

  # mock attributes:
  def getattr(self, name):
    return MockAny()

  # make it callable, if you need to
  def __call__(self, *a, **k):
    return MockAny()

当然,另一种选择是知道你在嘲笑什么(通过自省,或通过某种形式的“声明性描述”,或者只是通过为特定事物编写模拟代码;-)而不是采取包罗万象的方法; 但是,后者也是可行的,如您在上面的(部分)示例中所见。

就个人而言,我建议使用现有的模拟框架,例如pymox,而不是重新发明这个特定的轮子(此外,此类框架的源代码可能比对 SO 的合理简洁的响应更具指导性,例如这个;-)。

于 2010-07-31T03:07:32.877 回答
1

如果您在单元测试中调用类似的东西f.x.y.z(),那么您可能会尝试进行过多的测试。这些嵌套属性中的每一个都应包含在其特定类的单元测试中。

再看看你的Foo类,看看你是否可以在单元测试中测试它自己的行为。

也许不是您正在寻找的答案,但希望从长远来看会有所帮助。

于 2010-07-31T06:21:31.657 回答