解决嵌套属性中的AttributeErrors

时间:2010-07-31 02:50:15

标签: python nested-attributes

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

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

此示例应提供对此问题的一些见解:

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()有意义。

2 个答案:

答案 0 :(得分:3)

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

E.g:

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上的合理简洁响应更有启发性,像这样酮; - 。)

答案 1 :(得分:1)

如果您在单元测试中调用类似f.x.y.z()的内容,则可能是您尝试测试过多。这些嵌套属性中的每一个都应该由其特定类的单元测试覆盖。

再看一下你的Foo课程,看看你是否可以在单元测试中测试自己的行为。

也许不是你想要的答案,但希望从长远来看会有所帮助。