Python模拟补丁参数`new` vs`new_callable`

时间:2014-11-20 21:27:34

标签: python mocking

来自文档http://www.voidspace.org.uk/python/mock/patch.html

patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)
  

如果省略new,则将目标替换为MagicMock。如果patch被用作装饰器而new被省略,则创建的mock将作为额外参数传递给装饰函数。如果patch用作上下文管理器,则上下文管理器将返回创建的模拟。

     

new_callable允许您指定不同的类或可调用   对象,将被调用以创建新对象。默认情况下   使用MagicMock。

我想了解两者之间的差异,以及使用new_callable代替new

的情况

2 个答案:

答案 0 :(得分:21)

new是一个实际的对象; new_callable是用于创建对象的可调用对象。这两个不能一起使用(您可以指定替换或创建替换的函数;使用两者都是错误。)

>>> foo = 6
>>> with mock.patch('__main__.foo', new=7):
...   print foo
...
7
>>> with mock.patch('__main__.foo', new_callable=lambda : 8):
...   print foo
...
8

newmock.DEFAULT时,模拟对象是MagicMock个实例,因为new_callable的默认值为MagicMock

答案 1 :(得分:4)

<强> [编辑] 在那个答案中,我错过了new采取对象和new_callable可调用(工厂)的最重要的事情,正如@chepner所说的那样。我不删除它,因为它包含一些有用的注释。

通过挖掘代码https://code.google.com/p/mock/source/browse/mock.py#1266很明显,new您无法通过名义参数设置属性并使用specspec_set,因为它会引发{{1}异常。

TypeError可以是new_callable本身的子类,您可以在补丁定义中使用所有模拟工具。

确实没有记录这种行为,而http://www.voidspace.org.uk/python/mock/changelog.html#version-0-8-0中你找不到更多的行为。

  

补丁和patch.object的新new_callable参数允许你   传入一个类或可调用的对象(而不是MagicMock)   调用以替换正在修补的对象

无论如何,你不能使用这样的东西创建一个NonCallableMock签名的YourMockSubclass

myobject

但在这种情况下,您必须使用@patch("mymodule.myobject", new=YourMockSubclass(), spec=myobject)

new_callable

因此,每次需要非模拟的MagicMock模拟时,都必须使用@patch("mymodule.myobject", new_callable=YourMockSubclass, spec=myobject)

恕我直言,唯一有用的是嘲弄财产。