什么是Mock测试

 Mock测试就是在 测试过程 中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。这个虚拟的对象就是Mock对象。Mock对象就是真实对象在调试期间的代替品。关键步骤是使用一个接口来描述该对象,在测试过程中解耦掉这个接口或者方法。只通过接口来引用对象,目前一般用于单元测试或者自动化测试依赖第三方接口时所应用。

安装pytest-mock插件

pip install pytest-mock 

mock应用

mock常量

# mock_examples文件夹中functions.py
from .constants import CONSTANT_A  # CONSTANT_A = 1

def double():
    return CONSTANT_A * 2
# mock常量测试类
import mock_examples.functions
from mock_examples.functions import double


def test_mocking_constant_a(mocker):
    mocker.patch.object(mock_examples.functions, 'CONSTANT_A', 2)
    expected = 4  
    actual = double()  # now it returns 4, not 2

    assert expected == actua

mock函数

# main.py
from mock_examples.slow import api_call

def slow_function():
    api_result = api_call()
    # do some more stuff here
    return api_result
# slow.py
def api_call():
    time.sleep(3)
    return 9
# mock函数测试类
def test_slow_function_mocked_api_call(mocker):
    mocker.patch(
        # api_call is from slow.py but imported to main.py
        'mock_examples.main.api_call',
        return_value=5
    )

    expected = 5
    actual = slow_function()
    assert expected == actual

mock类

# slow.py
class Dataset:

    def __init__(self):
        self.data = None

    def load_data(self):
        time.sleep(4)
        self.data = 'slow data'
# main.py
def slow_dataset():
    dataset = Dataset()
    return dataset.load_data()
from mock_examples.main import slow_dataset

def test_mocking_class_method(mocker):
    expected = 'xyz'

    def mock_load(self):
        return 'xyz'

    mocker.patch(
        # Dataset is in slow.py, but imported to main.py
        'mock_examples.main.Dataset.load_data',
        mock_load
    )
    actual = slow_dataset()
    assert expected == actual

Monkey Patching全局mock

有时候测试需要调用依赖于全局设置的功能,或调用无法轻松测试的代码(如网络访问)修改测试环境变量信息等。 monkey patch fixture 可安全地设置/删除属性,Monkey patching主要针对模块和环境进行Mock。

后续想更加深入学习可了解spy、MagicMock

注意点:

  1. python版本>=3.5
  2. 在引入时mock,不是定义时
  3. mock需要在方法被调用前,不是调用后

参考文档:
https://changhsinlee.com/pytest-mock/
https://github.com/pytest-dev/pytest-mock
https://note.qidong.name/2018/02/pytest-mock/
https://pypi.org/project/pytest-mock/

Q.E.D.


Nothing really matters to me!