pytest monkeyPatch для функции API

#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!"