Рубрики
Без рубрики

Мачные внешние зависимости в Python

Тестирование модулей Python или код, имеющие любые внешние вызовы, такие как сторонние API-вызовы или база данных … Помечено Python, издевательство, тестирование.

Тестирование модулей Python или код, имеющих любые внешние вызовы, такие как сторонние вызовы API или вызовы базы данных, могут затруднить. Это где издевательства полезны.

Макеты обычно используются, когда:

  • Вызов третьей сторонней API является избыточным в сценариях тестирования (но требуется в фактической версии производства) I.e. Данные из внешнего сервиса не часто меняются, однако, что накладные перековы HTTP-адресов результатов.
  • Звонение третьей стороной – это только премиум-подписка (оплачена) I.e. У него нет среды тестирования жгута
  • Ответ от третьей партии не может быть легко контролируется, просто изменив входные данные I.E. Имитация ответов в угол, полученные внешние API.

Существует несколько способов внедрения издевательства ниже, является простым внедрением издевательства HTTP-сервиса, используя Unittest.mock Библиотека Отказ

MOCK HTTP-запрос

Предположим, что есть сервис, который дает температуру обратно, когда их запрошены с городом или местоположением:

Пример API “Get” выводится, как видно на браузере

Типичная библиотека вызывающих в клиентском коде будет реализовать что-то вроде:

import requests
import json

class ExternalServiceUtility:
    def __init__(self):
        super().__init__()

    # Function to make call to external service
    def get_current_temperature_using_service(self, location):
        _temperature_service_url = "http://127.0.0.1:5001/gettemparature/{0}" #in real life would be from configuration
        formatted_url = _temperature_service_url.format(location)
        current_temperature = None

        try:
            response_obj = requests.get(formatted_url)

            # check if we got a valid response
            if response_obj.status_code != 200:
                #some logging
                return current_temperature

            # parse the response 
            response_json = response_obj.json()
            current_temperature = response_json["Temperature"]

            return current_temperature
        except Exception as ex:
            # some logging and handling
            return current_temperature

И метод использования этой библиотеки будет выглядеть так:

from externalserviceutility import ExternalServiceUtility
def get_actual_temperature(location):
    extutil = ExternalServiceUtility()
    temperature = extutil.get_current_temperature_using_service(location)
    print(temperature)

get_actual_temperature("Regina")

Здесь мы можем захотеть проверить приложение, не вызывая конечную точку HTTP. Следовательно, реализация издевательства будет выглядеть ниже.

from externalserviceutility import ExternalServiceUtility
import requests
from unittest.mock import patch
import json

def alternate_mock_method(args):
    data = '{"Temperature": 100, "Location": "Toronto", "Datetime": "2020-07-23", "Units": "Celsius"}'
    r = requests.Response()
    r.status_code = 200
    def json_func():
        return json.loads(data)
    r.json = json_func
    return r  

@patch('requests.get',side_effect=alternate_mock_method)
def get_temperature_with_mock(location, args):
    extutil = ExternalServiceUtility()
    temperature = extutil.get_current_temperature_using_service(location)
    print(temperature)


get_temperature_with_mock("Regina")

Те же реализация может быть сделана для других глаголов в библиотеке, скажем, requests.post.post.

Детали реализации:

  • Включают в себя Unittest Myck Library и импорт на вершине
  • Украсьте метод, используя «патч». Все призывы к способу, объявленному в первом параметре патча, будут перенаправлены на имя функции, объявленного в качестве второго параметра i.e. Side_effect.
  • Теперь вместо того, чтобы сделать вызовы на внешнюю службу, реализация «alternate_Mock_Method» будет вызываться для каждого запроса. Получите запрос со всем дочерним кодом метода «get_temperature_with_mock». Метод. Способ, украшенный атрибутом патча.
  • Обратите внимание, что метод # get_temperature_with_mock требует дополнительного параметра в конце синтаксиса.

Осторожно: обратите внимание, что все звонки на requests.get . В рамках кодовой структуры дерева в издевательственном методе будет перенаправлена на заказ на заказ.

Оригинал: “https://dev.to/sridharanprasanna/mock-external-dependencies-in-python-2kac”