python mocking:mock.patch.object gotchas

时间:2015-08-27 17:57:35

标签: python mocking patch

我一直在编写单元测试超过一年,并且一直使用patch.object来处理所有事情(模块,类等)。

我的同事说,不应该使用patch.object来修补模块中的对象(即patch.object(socket, 'socket'),而应该始终使用patch('socket.socket')

我更喜欢patch.object方法,因为它允许我导入模块,在我看来更加pythonic。我的同事是对的吗?

注意:我查看了补丁文档,但未找到有关此主题的任何警告。 所有不是python中的对象吗?

2 个答案:

答案 0 :(得分:1)

没有这样的要求,是的,一切都是Python中的对象。

它只不过是一种风格选择;你自己导入模块或patch为你处理这个问题吗?因为这是两种方法之间的唯一区别;要么patch()导入模块,要么导入模块。

对于待测代码,我更喜欢mock.patch()来处理这个问题,因为这样可以确保在测试运行时进行导入。这可以确保我获得测试错误状态(测试失败),而不是加载测试时的问题。所有其他模块都是合理的游戏。

答案 1 :(得分:0)

看看模拟源代码,看起来确实没有区别。

为了调查我首先查看了def patch并看到它确实:

  getter, attribute = _get_target(target)
  return _patch(
     getter, attribute, new, spec, create,
     spec_set, autospec, new_callable, kwargs)

wheras patch.object做同样的事情,除了:getter = lambda: target

好的,那么_get_target做了什么?它几乎拆分字符串并在第一部分(创建一个对象)上调用_importer并使用与get_object相同的字符串。

_importer是一个非常简单的从模块导入的机制(对每个"组件"使用getattr),并且很明显只是创建一个对象。

所以从根本上说,在源级别,没有任何区别。

结案