Можно ли имитировать несколько типов запросов в одном методе тестирования?

#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 макет объекта метода).