python-3.x 使用mock有什么区别,Mock()对mock,patch(),以及何时使用一个而不是另一个?

fnvucqvd  于 2023-05-02  发布在  Python
关注(0)|答案(1)|浏览(162)
  1. mock.Mock()mock.patch()有什么区别?
    1.何时使用mock.Mock()以及何时使用mock.patch()
    1.我读到过Mock用来替换当前作用域中使用的东西,而patch用来替换在另一个作用域中导入和/或创建的东西。有人能解释一下这意味着什么吗?
  • 如果我们在一个单独的测试文件中进行测试,那么每一个被测试的类方法、静态方法、中间方法不是都要从开发/生产文件中导入吗?这是否意味着这里只能使用贴片?如果要在与被测代码相同的文件上进行测试,mock是首选吗?对吗?
f0ofjuux

f0ofjuux1#

我不确定我是否完全理解了你的问题,但我会给予。如文档中所述,Mock对象(实际上是MagickMock示例)是使用patch装饰器创建的:

from unittest.mock import patch

@patch('some_module.some_object')
def test_something(mocked_object):
    print(mocked_object)

这给出了类似于:

<MagicMock name='some_object' id='1870192381512'>

这相当于:

def test_something():
    with patch('some_module.some_object') as mocked_object:
        print(mocked_object)

这使您可以用模拟对象替换任何对象,以避免调用实际的生产代码和/或检查原始对象是如何调用的(如果对象是函数)。为什么首选使用patch(或一些类似的方法)的原因是,这可以确保补丁在测试之后(或在第二种情况下在上下文管理器范围之后)恢复,因此不会对其他测试或其他代码产生副作用。
引用文档:
补丁装饰器仅用于在它们装饰的函数范围内修补对象。即使出现异常,它们也会自动为您处理取消修补。所有这些函数也可以在with语句中使用或用作类装饰器。
您还可以手动创建一个Mock对象并将其分配给一个对象--我想这就是您问题中的意思。如果您这样做,而不是使用patch,您有责任自己重置之前的状态。由于这是更容易出错,我会建议专用的方法修补,如果可能的话。
在局部对象和其他模拟中,这并不重要。很少需要模拟本地对象,但Mock示例通常与修补对象一起创建,以保留模拟对象的示例供以后检查:

@mock.patch('my_functions.MyClass')
def test_object(mock_class):
    arg1 = Mock()
    arg2 = Mock()
    do_something(arg1, arg2)

    # check that do_something creates MyClass with the given arguments 
    mock_class.assert_called_with(arg1, arg2)

在这种情况下,case将仅用作模拟对象的参数,因此不需要重置。
总结如下:

  • patch是一个方便的装饰器/上下文管理器函数,用于将对象替换为mock对象(或其他对象),并在完成后或发生异常时重置先前的状态。
  • Mock或派生对象由mock.patch创建,也可以手动创建。手动创建的模拟通常仅用于修补不需要重置的本地函数或其他模拟。

相关问题