欢迎访问宙启技术站
智能推送

UnitTest中getMock、patch和MagicMock详解

发布时间:2023-12-25 06:39:53

在进行单元测试时,有时候我们需要模拟一些对象或函数的行为。为了实现这个目的,pytest提供了三个主要的工具:getMock、patch和MagicMock。下面我们将详细介绍这三个工具,并通过一些使用例子来说明它们的用法。

1. getMock():

getMock用于创建一个模拟对象,我们可以设置这个模拟对象的属性和方法以及它们的返回值。这个模拟对象的行为可以根据需要进行定制,从而满足测试的目标。

下面是一个使用getMock的例子:

from unittest.mock import Mock

def test_method():
    # 创建一个模拟对象
    mock_obj = Mock()
    # 设置模拟对象的属性
    mock_obj.name = 'mock'
    # 设置模拟对象的方法返回值
    mock_obj.method.return_value = 42

    # 使用模拟对象的属性和方法
    assert mock_obj.name == 'mock' # 断言属性的值
    assert mock_obj.method() == 42 # 断言方法的返回值

2. patch():

patch用于临时替换一个对象或函数,以模拟它的行为。我们可以使用patch装饰器或上下文管理器来使用patch。当离开装饰器或上下文管理器的范围后,被patch的对象或函数将恢复其原始行为。

下面是一个使用patch装饰器的例子:

from unittest.mock import patch

def method_to_patch():
    return 'original'

@patch('__main__.method_to_patch') # 使用patch装饰器
def test_method(mock_method):
    # 设置模拟函数的返回值
    mock_method.return_value = 'mocked'

    # 调用被模拟的函数
    assert method_to_patch() == 'mocked' # 断言模拟函数的返回值

下面是一个使用patch上下文管理器的例子:

from unittest.mock import patch

def method_to_patch():
    return 'original'

def test_method():
    with patch('__main__.method_to_patch') as mock_method: # 使用patch上下文管理器
        # 设置模拟函数的返回值
        mock_method.return_value = 'mocked'

        # 调用被模拟的函数
        assert method_to_patch() == 'mocked' # 断言模拟函数的返回值

3. MagicMock():

MagicMock是Mock的子类,它可以对属性和方法的调用进行更细粒度的控制。通过MagicMock,我们可以模拟出更复杂的行为,比如引发异常、记录调用和断言调用等。

下面是一个使用MagicMock的例子:

from unittest.mock import MagicMock

def test_method():
    # 创建一个MagicMock对象
    mock_obj = MagicMock()
    # 设置方法的返回值
    mock_obj.method.return_value = 42
    # 设置方法的调用行为
    mock_obj.method.side_effect = ValueError('mocked error')

    # 调用方法,断言返回值和异常
    assert mock_obj.method() == 42 # 断言返回值
    try:
        mock_obj.method() # 调用方法
    except ValueError as e:
        assert str(e) == 'mocked error' # 断言异常的消息

通过上面的例子,我们了解了getMock、patch和MagicMock这三个工具的基本用法。在编写单元测试时,我们可以根据具体的需求选择适合的工具来模拟对象或函数的行为,以达到更好的测试效果。