1.Patch简介
Patch库是Mock库提供的一种函数装饰器,用法非常灵活。Patch可以创建模拟并将其传递给装饰函数。对于复杂情况的模拟,也可以使用Patch方式进行模拟。也可以利用Patch装饰器的方式给模拟对象打补丁,但要注意作用域。
def patch(
target, new=DEFAULT, spec=None, create=False,
spec_set=None, autospec=None, new_callable=None, **kwargs
):
这里对几个参数进行具体的解释
target:必须是一个字符串类型,格式为包名.模块名.类名(或者函数名)。
new: 可以选择初始化的Mock类型,默认是MagicMock
spec=True或spec_set=True用于将Mock对象设置为spec/spec_set对象
new_callable:用于将Mock对象设置为可调用对象,默认情况下也使用MagicMock类型
2.Patch的简单用例
有时待测试接口未完成,不能直接进行测试,但是返回结果的结构用例是清楚的,那么可以针对这个返回的函数进行Patch处理。具体实例如下:
D:\python_record\tool.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/8 15:50
# @Author : ywb
# @Site :
# @File : tool.py
# @Software: PyCharm
def load_cheers():
return "这是一个还没有完成的函数,不会被真正调用"
D:\python_record\get_cheer_data.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/8 18:17
# @Author : ywb
# @Site :
# @File : get_cheer_data.py
# @Software: PyCharm
from tool import load_cheers
def create_cheers():
result = load_cheers()
return result
D:\python_record\test_get_cheer_data.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/8 18:20
# @Author : ywb
# @Site :
# @File : test_get_cheer_data.py
# @Software: PyCharm
import unittest
from unittest import mock
from get_cheer_data import create_cheers
class GetCheerDataTest(unittest.TestCase):
@mock.patch('get_cheer_data.load_cheers')
def test_get_cheer_data(self, mock_load):
mock_load.return_value = '这里是对真实的load_cheers函数进行模拟的一个返回值'
self.assertEqual(create_cheers(), '这里是对真实的load_cheers函数进行模拟的一个返回值')
if __name__ == '__main__':
unittest.main()
result:
Testing started at 18:25 ...
D:\software\python\python.exe "D:\software\PyCharm 2019.3.4\plugins\python\helpers\pycharm_jb_unittest_runner.py" --path D:/python_record/test_get_cheer_data.py
Launching unittests with arguments python -m unittest D:/python_record/test_get_cheer_data.py in D:\python_record
Ran 1 test in 0.003s
OK
Process finished with exit code 0
3.Patch使用总结
Patch主要是修饰替换多重嵌套调用的类方法或函数,可以指定为定义域内的任意函数方法。该函数装饰器是为了解决在后续依赖的调用函数发生变化的时候,Mock简单模拟替换上层调用函数或者类方法导致的单元测试和相关测试不通过的问题。
以这个例子为例,如果直接测试load_cheers()方法,应当使用mock对象。但是要通过调用create_cheers()方法来达到测试load_cheers()方法的目的,则只能使用Patch这个函数装饰器,当然,你如果说非要直接使用mock对象测试load_cheers()方法,也是可以的,但是代码维护量很大,且耗费人力,一旦依赖关系发生改变,改动量相当大。