Имитация нескольких запросов API отдельно в модульных тестах Python - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть модульный тест Flask views.py, который вызывает другой REST API.Как я могу специально смоделировать один из запросов?

Причина в том, что один из запросов вызовет некоторые операции, такие как фиксация в базе данных, перезапись в файл и т. Д., Если код состояния равен 200. Я хочучтобы проверить, вернется ли код состояния 200. Если да, я хочу запретить последующие операции в модульном тесте, а если нет, то он не затрагивает какие-либо последующие операции, так что не беспокойтесь.

Я также хочу, чтобы проверялосьзапрос никак не влияет на запрос приложения Flask, т. е. запрос приложения Flask не проверяется.

project / views.py

from flask import Flask
from project.another_dir.another_script import another_function

app = Flask(__name__)

@app.route('/api/abcde', methods=['POST'])
def post_something():
    another_function()

project / another_dir / another_script.py

import requests

def another_function():
    response = requests.post(<some_url>)    # this is the "requests" I want to mock

    if response.status_code == 200:
        # server working properly, commit database transaction / write to a file / trigger some other functions / ...
    else:
        # something's wrong with the server, send error for exception handling

Модульный тест

from unittest.mock import Mock
import pytest

headers = {'Authorization': 'Basic akd39K045Pw=='}
data = "some_data"

@pytest.fixture
def client():
    app.testing = True
    client = app.test_client()

    return client

@pytest.mark.parametrize("h, d, status_code", [
    (None, None, 401),  # no auth header, no data
    (None, data, 401),    # no auth header
    (headers, data, 200)  # with auth header and data
])
def test_views_post_something(client, h, d, status_code):

    ##### This is what I want to mock to avoid actually committing to db
    # from project.another_dir.another_script import requests
    # mock_request = Mock()
    # requests = mock_request
    ##### But no luck

    response = client.post('/api/abcde', headers=h, data=d)

    assert response.status_code == status_code

1 Ответ

0 голосов
/ 03 апреля 2019

Вы пробовали pook и unmock ?Они обслуживают разные варианты использования, но в данном случае это звучит так, как будто какашка лучше подходит.Pook работает хорошо, если запрос, над которым вы издеваетесь, не сильно изменится и имеет частный / внутренний API

Другой вариант - использовать инструмент, подобный docker-compose, для ускорения эфемерного стека с вашей базой данныхвыбор.Таким образом, вы можете разрешить выполнение запроса, не затрагивая хрупкие ресурсы, но это, как правило, медленнее и склонно к ошибкам, если вы пытаетесь воссоздать сложные состояния.Я обычно начинаю с подхода с низким уровнем касания, такого как pook или unmock, а затем собираю эфемерный стек для самых критически важных тестов.

...