为什么mock.patch.multiple与DEFAULT的行为不同?

时间:2015-11-27 20:30:31

标签: python mocking

如果将patch.multiple用作方法/函数装饰器,则如果修补对象为mock.DEFAULT,则其行为会有所不同。

示例:

from unittest import mock

class A: pass

@mock.patch.multiple('__main__', A=mock.DEFAULT)
def with_default(*args,**kwargs):
    if 'A' not in kwargs:
        print("with_default: A not passed")

@mock.patch.multiple('__main__', A=mock.Mock())
def with_other(*args, **kwargs):
    if 'A' not in kwargs:
        print("with_other: A not passed")

with_default() # nothing
with_other() # -> "with_other: A not passed"

我有没有看到这种行为的原因?在所有情况下,我都无法看到为什么它没有将新模拟传递给函数。

1 个答案:

答案 0 :(得分:0)

docs说(强调是我的):

  

如果希望std::vector创建模拟,请使用DEFAULT作为值   为了你。 在这种情况下,创建的模拟将传递到装饰中   按关键字起作用,并在返回字典时返回   patch.multiple()用作上下文管理器

因此,如果您不使用patch.multiple()关键字,则设置修补后的方法不会传递给修饰函数。

您的DEFAULT装饰案例可以重写为:

with_other

即使您使用@mock.patch('__main__.A', new=mock.Mock()) def with_other(): ... bla bla 属性,参数也不会传递给修饰函数,因为它假设您已经知道它并且您不需要将它作为参数。

一般来说:new可以用简单patch.multiple的堆栈替换,其中路径通过参数名称扩展,并使用patch来设置值:

new

成为

@patch.mutilple('foo', bar='bar', baz='baz')

或更简单的@patch('foo.baz', new='baz') @patch('foo.bar', new='bar') 位置参数:

new