#python #pytest #google-analytics-api #monkeypatching
Вопрос:
Я пишу несколько тестов, и во время работы с внешним API мне нужно создать несколько исправлений функций. Намеренно не резервный инженер проектирует API, а скорее создает патч для аналогичного поведения во время тестирования.
например, рассмотрим API «запросы», мы можем получить ответ от любого URL-адреса, позвонив requests.get('https:// URL')
. Исправление для этой функции приведено в документации monkeypatch.
Теперь рассмотрим другой API. Который намного сложнее и имеет функции вложенности. Теперь возникает вопрос, как именно мы можем создать патч для функции вложенности.
Пример кода
SomeAPIClass.function_1().function_2().execute()
Теперь вопрос в том, как именно я могу создать патч для execute()
функции. MonkeyPatch устанавливает атрибут для данной функции, но это просто происходит function_1()
так, как должно было бы быть monkeypatch.setattr(SomeAPIClass, "function_1", mock_get)
Комментарии:
1. Я добавил ответ. Не могли бы вы проверить, работает ли это на вашей стороне?
Ответ №1:
Мы можем имитировать цепные вызовы, вложив значение .return_value, как задокументировано:
mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response
Так что для вашего случая это было бы:
with patch('SomeAPIClass') as mock: # Or if using pytest-mock, this could simply be <mock = mocker.patch('SomeAPIClass')>
# To call: SomeAPIClass.function_1().function_2().execute()
mock.function_1.return_value.function_2.return_value.execute.return_value = "Execution result!"
# To call: SomeAPIClass().function_1().function_2().execute()
mock.return_value.function_1.return_value.function_2.return_value.execute.return_value = "Execution result!"
Пробный прогон
src.py
class SomeAPIClass:
pass
test_src.py
from unittest.mock import patch
import src
# Using unittest.mock
def test_patch():
with patch('src.SomeAPIClass') as mock:
mock.function_1.return_value.function_2.return_value.execute.return_value = "Execution result!"
assert src.SomeAPIClass.function_1().function_2().execute() == "Execution result!"
mock.return_value.function_1.return_value.function_2.return_value.execute.return_value = "Execution result 2!"
assert src.SomeAPIClass().function_1().function_2().execute() == "Execution result 2!"
# Using pytest-mock's mocker
def test_patch_2(mocker):
mock = mocker.patch('src.SomeAPIClass')
mock.function_1.return_value.function_2.return_value.execute.return_value = "Execution result!"
assert src.SomeAPIClass.function_1().function_2().execute() == "Execution result!"
mock.return_value.function_1.return_value.function_2.return_value.execute.return_value = "Execution result 2!"
assert src.SomeAPIClass().function_1().function_2().execute() == "Execution result 2!"