我正在写一个小型的模拟课来做一些测试。
但是这个类需要支持嵌套属性的想法。
此示例应提供对此问题的一些见解:
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()
有意义。
答案 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
课程,看看你是否可以在单元测试中测试自己的行为。
也许不是你想要的答案,但希望从长远来看会有所帮助。