Как замокать response в pytest?
Каким инструментом и как лучше замокать ответ, получаемый функцией от сервера? Посоветуйте чем вы пользуетесь для таких случаев.
Ну, например какая-нибудь такая функция
def my_func():
products = requests.get('http://some-site.ru/some-page').json().get('products')
return products
def test_my_func():
products = my_func()
assert products[0].get('name') = 'Холодильник'
Вот как сделать так, чтобы в products попали тестовые данные в тесте?
Ответы (2 шт):
Автор решения: AivanF.
→ Ссылка
Надо инкапсулировать:
- Можно вынести адрес хоста куда-то вовне, чтобы во время теста составлять другой URL. Попутно поднять мок-сервер по этому адресу, чтобы отвечал нужными данными.
HOST = 'http://some-site.ru'
if mode == 'test':
# как вариант
HOST = '127.0.0.1:8800'
def get_products():
products = requests.get(f'{HOST}/some-page').json().get('products')
- Вариант попроще и в то же время мощнее, создать базовый класс по работе с данными, в одном его наследнике будут отправляться реальные запросы куда нужно, а в другом специальном классе-наследнике будут возвращаться фейковые данные для тестов. При этом, здесь тоже можно легко провернуть работу с полноценным мок-сервером.
class DataProvider:
# тут можно определить абстрактные методы и т.п
pass
class ServerDataProvider(DataProvider):
def __init__(host):
self.host = host
def get_products():
products = requests.get(f'{self.host}/some-page').json().get('products')
return products
class FakeDataProvider(DataProvider):
def __init__():
pass
def get_products():
products = [ ... ] # любые фейковые данные
return products
if mode == 'test':
data_provider = FakeDataProvider()
else:
data_provider = ServerDataProvider(host='http://some-site.ru')
mode можно ставить как где-то в других модулях, так и на основе переменных окружения или консольных аргументов (например, банально ища там подстроку test).
Автор решения: hoefling
→ Ссылка
Хорошая библиотека requests-mock. Использование вполне прозрачное - регистрируй желаемые ответы на комбинации URL + method. Пример теста для my_func:
def test_my_func(requests_mock):
payload = {'products': [{'name': 'Холодильник'}]}
requests_mock.register_uri('GET', 'http://some-site.ru/some-page', json=payload)
products = my_func()
assert products[0].get('name') == 'Холодильник'