mock就是测试过程中,对一些不容易获取的数据,创建一个虚拟的对象以便测试,这个虚拟的对象就是Mock对象。一般用于单元测试或自动化测试依赖第三方接口时应用。
init
name
-
return_value
-
side_effect
覆盖return_value,当mock对象被调用时,返回该值,一般是异常返回或者是一个list/tuple ```python
mock_test.py
import requests
def mock_request(url): return requests.get(url=url).status_code
def invoke_mock_request(url): return mock_request(url)
```python# test_mock_1.pyimport pytestfrom api_testcases.mock_test import invoke_mock_request, mock_requestdef test_mock_init(mocker):"""patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)target:传入当前需要mock的方法(接口),字符串格式name:mock对象的名称return_value:mock对象被调用的返回值side_effect:覆盖return_value,当mock对象被调用时,返回该值,一般是异常返回或者是一个list/tuplespec:设置mock对象的属性"""init_mocker = mocker.patch('api_testcases.mock_test.mock_request', name='test mocker init',return_vlaue=mock_request)invoke_mock_request(URL)init_mocker.assert_called()side_effect_list = [200]# 当side_effect被设置的时候,return_value就不起作用了,side_effect被设置为一个异常也可以被指定的参数的值是一个list或者tupleside_effect_mocker = mocker.patch('api_testcases.mock_test.mock_request', name='test mocker init',return_vlaue=mock_request, side_effect=side_effect_list)assert invoke_mock_request(URL) == side_effect_list[0]side_effect_mocker.assert_called()if __name__ == "__main__":pytest.main()"""============================= test session starts ==============================platform darwin -- Python 3.7.7, pytest-6.2.4, py-1.10.0, pluggy-0.13.1rootdir: /Users/zaygee/pytest_test, configfile: pytest.iniplugins: allure-pytest-2.9.42, mock-3.6.1, xdist-2.2.1, forked-1.3.0collected 1 itemtest_mock_1.py::test_mock_init PASSED [100%]============================== 1 passed in 0.02s ==============================="""
spec
import pytest
class Foo(object): _num = 10
def test_mocker_spec(mocker):
# 指定属性listspec_list = ['_value', 'callFunc']mocker_spec = mocker.patch('api_testcases.mock_test.mock_request', spec=spec_list)logger.info(mocker_spec._value)# 执行类属性mocker_class_spec = mocker.patch('api_testcases.mock_test.mock_request', spec=Foo)logger.info(mocker_class_spec._num)
if name == “main“: pytest.main()
“”” ============================= test session starts ============================== platform darwin — Python 3.7.7, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 rootdir: /Users/zaygee/pytest_test, configfile: pytest.ini plugins: allure-pytest-2.9.42, mock-3.6.1, xdist-2.2.1, forked-1.3.0 collected 1 item
test_mock_1.py::test_mocker_spec
———————————————— live log call ————————————————-
2021-08-29 22:47:02 INFO
============================== 1 passed in 0.02s =============================== “””
<a name="oGUkf"></a>### 断言1. **assert_called**:检查mock对象至少被调用一次1. **assert_not_called**:检查mock对象没有被调用1. **assert_called_once**:检查mock对象只被调用一次1. **assert_called_with:**检查mock对象的参数是否正确1. **assert_called_once_with**:检查mock对象只被调用一次1. **assert_any_call**:检查mock对象在全局过程中是否调用了该方法```pythonimport pytestfrom api_testcases.mock_test import invoke_mock_request, mock_requestfrom common import loggerURL = 'https://docs.cypress.io/'def test_mock_request(mocker):mocker_inst = mocker.patch('api_testcases.mock_test.mock_request', return_value=mock_request, name='test mock')assert invoke_mock_request(URL) == mocker_inst.return_value# 断言至少被调用一次mocker_inst.assert_called()# 断言只被调用一次mocker_inst.assert_called_once()# 断言mock对象的参数是否正确mocker_inst.assert_called_with(URL)# 断言mock对象是否没有被调用# mocker_inst.assert_not_called()mocker_inst.assert_called_once_with(URL)# 断言对象在全局过程中是否调用了该方法mocker_inst.assert_any_call(URL)logger.info(mocker_inst)if __name__ == "__main__":pytest.main()"""============================= test session starts ==============================platform darwin -- Python 3.7.7, pytest-6.2.4, py-1.10.0, pluggy-0.13.1rootdir: /Users/zaygee/pytest_test, configfile: pytest.iniplugins: allure-pytest-2.9.42, mock-3.6.1, xdist-2.2.1, forked-1.3.0collected 1 itemtest_mock_1.py::test_mock_request-------------------------------- live log call ---------------------------------2021-08-29 22:51:22 INFO <MagicMock name='test mock' id='140218070657296'>PASSED [100%]============================== 1 passed in 0.01s ==============================="""
# mock_test.pyimport requestsdef mock_request(url):return requests.get(url=url).status_codedef invoke_mock_request(url):return mock_request(url)# test_mock_1.pyimport mockimport pytestfrom mock import Mockfrom api_testcases.mock_test import invoke_mock_request, mock_requestdef test_mock_request():with mock.patch('api_testcases.mock_test.mock_request', return_value=200, side_effect=mock_request) as mock_foo:assert invoke_mock_request(URL) == mock_foo.return_value@mock.patch('api_testcases.mock_test.mock_request', return_value=300)def test_mock_request1(mock_request):assert invoke_mock_request(URL) == mock_request.return_valueif __name__ == "__main__":pytest.main()"""============================= test session starts ==============================platform darwin -- Python 3.7.7, pytest-6.2.4, py-1.10.0, pluggy-0.13.1rootdir: /Users/zaygee/pytest_test, configfile: pytest.iniplugins: allure-pytest-2.9.42, mock-3.6.1, xdist-2.2.1, forked-1.3.0collected 2 itemstest_mock_1.py::test_mock_request PASSED [ 50%]test_mock_1.py::test_mock_request1 PASSED [100%]============================== 2 passed in 0.63s ==============================="""
mock管理方法
- attach_mock:将一个mock对象添加到另一个mock对象中
- configure_mock:修改mock对象的return_value值 ```python import pytest from api_testcases.mock_test import invoke_mock_request, mock_request, TestMock1, TestMock2 from common import logger
def test_mock_management(mocker): mocker_attach_1 = mocker.patch(‘api_testcases.mock_test.TestMock1’) mocker_attach_2 = mocker.patch(‘api_testcases.mock_test.TestMock2’) logger.info(mocker_attach_1._value1) logger.info(mocker_attach_1.func1) logger.info(mocker_attach_2)
# 调用attach_mock方法,将mocker_attach_2 添加到mocker_attach_1中,重命名为mock_attachmocker_attach_1.attach_mock(mocker_attach_2, 'mock_attach')logger.info(mocker_attach_1.func1)logger.info(mocker_attach_1.mock_attach.func2)# configure_mock方法,修改mock对象的return_value值mocker_attach_3 = mocker.patch('api_testcases.mock_test.mock_request')mocker_attach_3.configure_mock(return_value=100)assert invoke_mock_request(URL) == 100
if name == “main“: pytest.main()
“”” ============================= test session starts ============================== platform darwin — Python 3.7.7, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 rootdir: /Users/zaygee/pytest_test, configfile: pytest.ini plugins: allure-pytest-2.9.42, mock-3.6.1, xdist-2.2.1, forked-1.3.0 collected 1 item
test_mock_1.py::test_mock_management
———————————————— live log call ————————————————-
2021-08-29 23:00:40 INFO
============================== 1 passed in 0.01s =============================== “”” ```
