#python #python-3.x #unit-testing #python-requests
#питон #python-3.x #модульное тестирование #python-запросы
Вопрос:
Можно ли имитировать несколько типов запросов ( GET
, POST
, PUT
и т. Д.) В одном методе? Я могу издеваться над одним типом запроса с mock.patch
помощью декоратора. Но как я могу издеваться над несколькими типами в одном методе тестирования? Я ищу для этого питоническое и элегантное решение (я бы предпочел mock.patch
декоратора, но я открыт и для других решений).
Вы можете увидеть ниже пример моей проблемы:
source.py
import requests def source_function(): x = requests.get("get_url.com") requests.post("post_url.com/{}".format(x.text))
test.py
import unittest from unittest import mock from source import source_function class TestCases(unittest.TestCase): @mock.patch("requests.get") def test_source_function(self, mocked_get): mocked_get.return_value = mock.Mock(status_code=201, json=lambda: {"data": {"id": "test"}}) source_function() # The POST request is not mocked.
Комментарии:
1. Вам нужно исправить
source.requests.get
, таким образом, место, где происходит фактический вызов.2. Конечно, я делаю это в производственном коде, но это не решает мою проблему. Как я могу имитировать типы запросов GET и POST в одном методе тестирования? Это мой вопрос.
3. Ты можешь издеваться сколько угодно. попробуйте издевательские
post
методы и получите ошибку?4. Я могу издеваться над GET/POST/PUT и т. Д. Отдельно, Но я не знаю, как мне следует издеваться над ними в одном методе тестирования.
Ответ №1:
Я нашел решение. Мне нужно было только передать один за другим макетные объекты.
source.py
import requests def source_function(): x = requests.get("http://get_url.com") print("Get resp: {}".format(x.json())) y = requests.post("http://post_url.com") print("Post resp: {}".format(y.json()))
test.py
import unittest from unittest import mock import source class TestCases(unittest.TestCase): @mock.patch("source.requests.get") @mock.patch("source.requests.post") def test_source_function(self, mocked_post, mocked_get): mocked_get.return_value = mock.Mock(status_code=200, json=lambda: {"data_get": {"id": "test"}}) mocked_post.return_value = mock.Mock(status_code=200, json=lambda: {"data_post": {"id": "test"}}) source.source_function() # Entry point of script. if __name__ == "__main__": unittest.main()
Выход:
gt;gt;gt; python3 test.py Get resp: {'data_get': {'id': 'test'}} Post resp: {'data_post': {'id': 'test'}} . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Важна только последовательность. Макет объекта верхнего декоратора должен быть последним (в моем случае GET
макет объекта метода).