| mock.create_autospec?方法为类提供了一个同等功能实例.实际上来说,这意味着在使用返回的实例进行交互的时候,如果使用了非法的方式将会引发异常.更具体地说,如果一个方法被调用时的参数数目不正确,将引发一个异常.这对于重构来说是非常重要.当一个库发生变化的时候,中断测试正是所期望的.如果不使用 auto-spec,尽管底层的实现已经被破坏,我们的测试仍然会通过.
 陷阱:mock.Mock 和 mock.MagicMock 类mock?库包含了两个重要的类?mock.Mock[5]?和?mock.MagicMock[6],大多数内部函数都是建立在这两个类之上的.当在选择使用?mock.Mock?实例、mock.MagicMock?实例还是 auto-spec 的时候,通常倾向于选择使用 auto-spec,因为对于未来的变化,它更能保持测试的健全.这是因为?mock.Mock?和?mock.MagicMock?会无视底层的 API,接受所有的方法调用和属性赋值.比如下面这个用例:
 
class Target(object): ? ?def apply(value): ? ? ? ?return valuedef method(target, value): ? ?return target.apply(value) 我们可以像下面这样使用 mock.Mock 实例进行测试: 
class MethodTestCase(unittest.TestCase): ? ?def test_method(self): ? ? ? ?target = mock.Mock() ? ? ? ?method(target, "value") ? ? ? ?target.apply.assert_called_with("value") 这个逻辑看似合理,但如果我们修改?Target.apply?方法接受更多参数: 
class Target(object): ? ?def apply(value, are_you_sure): ? ? ? ?if are_you_sure: ? ? ? ? ? ?return value ? ? ? ?else: ? ? ? ? ? ?return None 重新运行你的测试,你会发现它仍能通过.这是因为它不是针对你的 API 创建的.这就是为什么你总是应该使用create_autospec?方法,并且在使用?@patch和?@patch.object?装饰方法时使用?autospec?参数. 现实例子:模拟 Facebook API 调用作为这篇文章的结束,我们写一个更加适用的现实例子,一个在介绍中提及的功能:发布消息到 Facebook.我将写一个不错的包装类及其对应的测试用例. 
import facebookclass SimpleFacebook(object): ? ?def __init__(self, oauth_token): ? ? ? ?self.graph = facebook.GraphAPI(oauth_token) ? ?def post_message(self, message): ? ? ? ?"""Posts a message to the Facebook wall.""" ? ? ? ?self.graph.put_object("me", "feed", message=message) 这是我们的测试用例,它可以检查我们发布的消息,而不是真正地发布消息: 
import facebookimport simple_facebookimport mockimport unittestclass SimpleFacebookTestCase(unittest.TestCase): ? ?@mock.patch.object(facebook.GraphAPI, 'put_object', autospec=True) ? ?def test_post_message(self, mock_put_object): ? ? ? ?sf = simple_facebook.SimpleFacebook("fake oauth token") ? ? ? ?sf.post_message("Hello World!") ? ? ? ?# verify ? ? ? ?mock_put_object.assert_called_with(message="Hello World!") 正如我们所看到的,在 Python 中,通过 mock,我们可以非常容易地动手写一个更加智能的测试用例. Python Mock 总结即使对它的使用还有点不太熟悉,对单元测试[7]来说,Python的mock库可以说是一个规则改变者.我们已经演示了常见的用例来了解了mock在单元测试中的使用,希望这篇文章能够帮助Python开发者[8]克服初期的障碍,写出优秀、经受过考验的代码. 
 via:https://www.toptal.com/python/an-introduction-to-mocking-in-python 作者:NAFTULITZVIKAY[9]译者:cposture[10]校对:wxy[11] (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |