Python 3 Pytest: Как смоделировать запрос urlopen, ответ и заголовки? - PullRequest
0 голосов
/ 08 января 2020

Я разбил свой код на отдельные функции для модульного тестирования. Я пытаюсь подобрать среду тестирования Pytest и пока знаю только основы.

На самом деле я не хочу отправлять запрос в inte rnet - это будет бесполезный тест, так как я все равно буду проверять библиотеку urllib. Однако я хочу проверить, как обрабатывается ответ.

У меня есть эта функция, чтобы сделать запрос

def request_url(url):
    return request.urlopen(url)

И затем я проверяю тип содержимого:

def get_document_type(req):
    """ checks if document is html or plain text """
    doc_type = req.info().get_content_type()
    if doc_type == "text/html":
        return "html"
    elif doc_type == "text/plain":
        return "txt"
    else: 
        return error_message["unsupported_document_type"]

Затем мне нужно будет проверить, и я буду надо издеваться над каждым исходом. Если бы это было Node.js, я мог бы использовать что-то вроде rewire или заглушки sinon.

def get_content(req):
    doc_type_response = get_document_type(req)
    if doc_type_response == "html":
        # handle html content
    elif get_type_response == "txt":
        # handle plain text
    else:
        return doc_type_response

Этот модульный тест работает, но я не хочу делать реальный звонок.

def test_request_url():
    url = request_url(url_to_try).info().get_content_type() 
    assert url == "text/plain"

Кто-нибудь знает лучший способ сделать это, пожалуйста?

1 Ответ

0 голосов
/ 09 января 2020

Существует пакет-макет запросов https://pypi.org/project/requests-mock/, который можно использовать для насмешливых вызовов API, но для библиотеки запросов. Это пример с заголовками / текст

import unittest
import requests_mock
import requests

class TestImplementations(unittest.TestCase):

    @requests_mock.mock()
    def test_get_project(self, mock_for_requests):
        API_URL = "https://someapi.com"

        #mocking your request(s)
        expected_headers = {'Content-Type': 'text/plain'}
        expected = 'some_text'
        mock_for_requests.get(API_URL + "/someendpoint", headers=expected_headers, text=expected)

        #running your code with requests
        response = requests.get(API_URL + "/someendpoint")

        #comparing output
        self.assertEqual(response.headers, expected_headers)
        self.assertEqual(response.text, expected)
...