Ren*_*aby 9 python patch python-3.x python-unittest python-unittest.mock
mock.Mock()
使用vs 和有什么区别mock.patch()
?
何时使用mock.Mock()
以及何时使用mock.patch()
我读过 Mock 用于替换当前作用域中使用的内容,而 patch 用于替换在另一个作用域中导入和/或创建的内容。有人能解释一下这是什么意思吗?
MrB*_*men 17
我不完全确定我是否理解你的问题,但我会尝试一下。如文档中所述,Mock
对象(实际上是MagickMock
实例)是使用patch
装饰器创建的:
from unittest.mock import patch
@patch('some_module.some_object')
def test_something(mocked_object):
print(mocked_object)
Run Code Online (Sandbox Code Playgroud)
这给出了类似的东西:
<MagicMock name='some_object' id='1870192381512'>
Run Code Online (Sandbox Code Playgroud)
这相当于:
<MagicMock name='some_object' id='1870192381512'>
Run Code Online (Sandbox Code Playgroud)
这使您可以用模拟对象替换任何对象,以避免调用实际的生产代码和/或检查原始对象的调用方式(如果该对象是函数)。首选使用(或某些类似方法)的原因patch
是,这可以确保在测试之后(或在第二种情况下在上下文管理器范围之后)恢复补丁,因此对其他测试或其他代码没有副作用。
引用文档:
补丁装饰器仅用于在它们装饰的函数范围内修补对象。即使出现异常,它们也会自动为您处理取消补丁的操作。所有这些函数也可以在 with 语句中使用或用作类装饰器。
您还可以Mock
手动创建一个对象并将其分配给一个对象 - 我认为这就是您在问题中的意思。如果您这样做而不是使用patch
,您有责任自行重置之前的状态。由于这更容易出错,如果可能的话,我建议使用专用的修补方法。
这在本地对象和其他模拟中并不重要。很少需要模拟本地对象,但Mock
实例通常与修补对象一起创建,以保留模拟对象的实例以供以后检查:
def test_something():
with patch('some_module.some_object') as mocked_object:
print(mocked_object)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,该 case 将仅用作模拟对象的参数,因此不需要重置。
总结一下:
patch
是一个方便的装饰器/上下文管理器功能,用于用模拟对象(或其他对象)替换对象,并在完成后或发生异常时重置先前的状态Mock
或派生对象由 创建mock.patch
,也可以手动创建。手动创建的模拟通常仅用于修补本地函数或其他不需要重置的模拟。