【发布时间】:2016-06-17 06:20:48
【问题描述】:
我有一个入口点函数调用它main 在一个我想保持未模拟的对象上,因为它在该对象上调用了几个其他方法:
class Thing(object):
def main(self):
self.alpha()
self.bravo()
def alpha(self):
self.charlie()
def bravo(self):
raise TypeError("Requires Internet connection!")
def charlie(self):
raise Exception("Bad stuff happens here!")
这很容易手动模拟:
thing = Thing()
thing.alpha = MagicMock()
thing.bravo = MagicMock()
我可以测试以确保 alpha 和 bravo 都被调用一次,我可以在 alpha 和 bravo 中设置副作用以确保它们被处理等等。
我担心的是如果代码定义发生变化并且有人向main 添加了charlie 调用。它没有被嘲笑,所以现在会感觉到副作用(它们就像写入文件,连接到数据库,从 Internet 获取东西,所以这个简单的异常不会提醒我测试现在坏的)。
我的计划是验证我的模拟对象除了我说它应该调用的方法之外没有调用其他方法(或引发测试异常)。但是,如果我这样做:
MockThing = create_autospec(Thing)
thing = Thing()
thing.main()
print thing.method_calls
# [calls.main()]
然后main 也被模拟,因此它不调用其他方法。除了主要方法,我如何模拟 每个方法? (我希望 method_calls 是 [calls.alpha(), calls.bravo()])。
编辑:用于破解答案
嗯,我有一个非常老套的解决方案,但我希望有比这更好的答案。基本上我重新绑定了原始类的方法(Python bind an unbound method)
MockThing = create_autospec(Thing)
thing = MockThing()
thing.main = Thing.ingest.__get__(thing, Thing)
thing.main()
print thing.method_calls
# [calls.alpha(), calls.bravo()]
但必须有比使用函数描述符更简单的解决方案!
【问题讨论】:
-
我收到错误消息“对象没有“摄取”属性,知道是什么原因造成的吗?我正在使用 Python 2.7
标签: python python-unittest python-mock