У кого-нибудь есть пример модульного тестирования SOAP API с использованием Python Zeep и Mock? - PullRequest
0 голосов
/ 24 декабря 2018

Я создаю приложение Python, которое обращается к стороннему API SOAP с помощью Python-zeep.Я хочу реализовать некоторые юнит-тесты, используя ложные ответы, так как у меня не всегда есть работающий сервер для выполнения моих тестов.

Я новичок в юнит-тестировании и не совсем уверен, с чего начать.Я видел примеры использования mock с библиотекой запросов, но не совсем уверен, как перевести это в Zeep.

В одной из моих моделей у меня есть метод для получения всех DevicePools из SOAP API.Вот выдержка из соответствующего кода (я использую вспомогательный метод для предоставления объекта службы, поскольку я планирую использовать это во многих других методах).

# Get Zeep Service Object to make AXL API calls
service = get_axl_client(self)

# Get list of all DevicePools present in the cluster
resp = service.listDevicePool(searchCriteria={'name': '%'},
                              returnedTags={'name': '', 'uuid': ''})

Я хочу смоделировать объект resp, однако этотипа zeep.objects.ListDevicePoolRes (динамический тип, основанный на разборе WSDL), и я не могу просто создать экземпляр объекта со статическими значениями.

Может быть, я здесь не на том пути, и мне нужно было бы пойти немного глубже и на самом деле посмеяться над некоторыми внутренностями библиотеки zeep и заменить ответ на запросы до того, как zeep проанализирует XML?

Еслиу кого-то был пример чего-то подобного, это было бы очень признательно.

1 Ответ

0 голосов
/ 31 декабря 2018

Изучив исходный код Python Zeep, я нашел несколько примеров тестов с использованием библиотеки arguments-mock, которые я смог использовать в своем решении.Вот рабочий пример на тот случай, если кто-то еще пытается сделать что-то подобное.

Я не делаю никаких утверждений в этом примере, поскольку сначала я хотел доказать концепцию, что я могу получить Zeep для правильного анализа ложного ответа..

# -*- coding: utf-8 -*-

from zeep import Client
from zeep.cache import SqliteCache
from zeep.transports import Transport
from zeep.exceptions import Fault
from zeep.plugins import HistoryPlugin
from requests import Session
from requests.auth import HTTPBasicAuth
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning
from lxml import etree
import requests_mock

disable_warnings(InsecureRequestWarning)

username = 'administrator'
password = 'password'
host = 'cucm-pub'

wsdl = 'file://C:/path/to/axlsqltoolkit/schema/current/AXLAPI.wsdl'
location = 'https://{host}:8443/axl/'.format(host=host)
binding = "{http://www.cisco.com/AXLAPIService/}AXLAPIBinding"

session = Session()
session.verify = False
session.auth = HTTPBasicAuth(username, password)

transport = Transport(cache=SqliteCache(), session=session, timeout=20)
history = HistoryPlugin()
client = Client(wsdl=wsdl, transport=transport, plugins=[history])
service = client.create_service(binding, location)

def test_listPhone():
    text = """<?xml version="1.0" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <ns:listDevicePoolResponse xmlns:ns="http://www.cisco.com/AXL/API/11.5">
      <return>
        <devicePool uuid="{1B1B9EB6-7803-11D3-BDF0-00108302EAD1}">
          <name>AU_PER_DP</name>
        </devicePool>
        <devicePool uuid="{BEF5605B-1DB0-4157-0176-6C07814C47AE}">
          <name>DE_BLN_DP</name>
        </devicePool>
        <devicePool uuid="{B4C65CAB-86CB-30FB-91BE-6F6E712CACB9}">
          <name>US_NYC_DP</name>
        </devicePool>
      </return>
    </ns:listDevicePoolResponse>
  </soapenv:Body>
</soapenv:Envelope>
    """


    with requests_mock.Mocker() as m:
        m.post(location, text=text)
        resp = service.listDevicePool(searchCriteria={'name': '%'},
                                      returnedTags={'name': '',
                                                    'uuid': ''})

    return resp

test_listPhone()

Это затем дает мне следующий результат (вручную удалил все атрибуты с «none», которые Zeep включает для краткости):

{
    'return': {
        'devicePool': [
            {
                'name': 'AU_PER_DP',
                'uuid': '{1B1B9EB6-7803-11D3-BDF0-00108302EAD1}'
            },
            {
                'name': 'DE_BLN_DP',
                'uuid': '{BEF5605B-1DB0-4157-0176-6C07814C47AE}'
            },
            {
                'name': 'US_NYC_DP',
                'uuid': '{B4C65CAB-86CB-30FB-91BE-6F6E712CACB9}'
            }
        ]
    },
    'sequence': None
}
...