Подменить данные googleapiclient с помощью unittest
Есть функция, которую нужно протестировать:
def get_id_object_by_name(name: str, folder_id: str = None) -> str:
"""Подключается к Google Drive и получает id папки или файла, по названию,
переданному в аргументе и возвращает его в виде {название: id}."""
service = auth_gdrive()
if folder_id:
query = f"name = '{name}' and '{folder_id}' in parents"
else:
query = f"name = '{name}'"
r = service.files().list(pageSize=10,
fields="nextPageToken, files(id, name, mimeType)",
q=query).execute()
if r["files"]:
logger.debug(f"Получен id файла {name} в папке с id '{folder_id}'.")
return r["files"][0]["id"]
else:
logger.debug(f"id файла {name} в папке {folder_id} не найден. "
f"Проверьте наличие файла в папке с id {folder_id} '.")
Я нашел способ подмены ответа запроса в документации гугла: google-api-python-client
http = HttpMock('books-discovery.json', {'status': '200'})
api_key = 'your_api_key'
service = build('books', 'v1', http=http, developerKey=api_key)
request = service.volumes().list(source='public', q='android')
http = HttpMock('books-android.json', {'status': '200'})
response = request.execute(http=http)
В файл books-android.json я положил ответ, который я хотел бы получить:
{
"files": [
{
"id": "345245634",
"name": "main-log-1",
"mimeType": "text/plain"
}
]
}
И есть сам модуль с тестом:
import unittest
from unittest.mock import patch
from google_drive.uploader import get_id_object_by_name
from googleapiclient.discovery import build
from googleapiclient.http import HttpMock
class TestGetId(unittest.TestCase):
def test_get_id_by_name(self):
http = HttpMock('books-discovery.json', {'status': '200'})
api_key = 'your_api_key'
service = build('books', 'v1', http=http, developerKey=api_key)
request = service.volumes().list(source='public', q='android')
http = HttpMock('books-android.json', {'status': '200'})
response = request.execute(http=http)
result = get_id_object_by_name()
Как мне подменить результат ответа API внутри функции get_id_object_by_name()
?
Пока что пришел к этому:
import unittest
from unittest.mock import patch, MagicMock
from google_drive.uploader import get_id_object_by_name
class TestGetId(unittest.TestCase):
@patch('google_drive.uploader.auth_gdrive')
def test_get_id_by_name(self, mock_auth_gdrive):
# Создаем замоканный объект Google Drive API
mock_service = MagicMock()
mock_files = MagicMock()
mock_list_request = MagicMock()
# Настраиваем цепочку вызовов для auth_gdrive
mock_auth_gdrive.return_value = mock_service
mock_service.files.return_value = mock_files
mock_files.list.return_value = mock_list_request
http = HttpMock('books-discovery.json', {'status': '200'})
api_key = 'your_api_key'
service = build('books', 'v1', http=http, developerKey=api_key)
request = service.volumes().list(source='public', q='android')
http = HttpMock('books-android.json', {'status': '200'})
response = request.execute(http=http)
# Указываем, что вернет метод execute()
mock_list_request.execute.return_value = response
# Вызываем тестируемую функцию
result = get_id_object_by_name('main-log-1', 'test_folder')
# Проверяем результат
self.assertEqual(result, '345245634', "ID файла должен быть '345245634'")
self.assertIsInstance(result, str, "Возвращаемое значение должно быть строкой")
if __name__ == "__main__":
unittest.main()
Результат тестов:
python -m unittest
DEBUG:google_drive.uploader:Запуск автозагрузчика...
Данные, возвращаемые функцие get_id_object_by_name: {'files': [{'mimeType': 'text/plain', 'id': '13_Vm_DH-sKuP-wWRTDUuxOPwiq_Q6-FN', 'name': 'main_log_i-analytic7.pz.cp.log'}]}
DEBUG:google_drive.uploader:Получен id файла main_log_i-analytic7.pz.cp.log в папке с id '15U_0EiHwodg1HU-7heyB5fNFWjy8Ua9p'.
13_Vm_DH-sKuP-wWRTDUuxOPwiq_Q6-FN
C:\Users\DOrlov\AppData\Local\Programs\Python\Python313\Lib\unittest\mock.py:2245: ResourceWarning: unclosed <ssl.SSLSocket fd=1356, family=2, type=1, proto=0, laddr=('192.168.104.11', 58355
), raddr=('209.85.233.95', 443)>
def __init__(self, name, parent):
ResourceWarning: Enable tracemalloc to get the object allocation traceback
C:\Users\DOrlov\AppData\Local\Programs\Python\Python313\Lib\unittest\mock.py:2245: ResourceWarning: unclosed <ssl.SSLSocket fd=1372, family=2, type=1, proto=0, laddr=('192.168.104.11', 58356
), raddr=('173.194.220.95', 443)>
def __init__(self, name, parent):
ResourceWarning: Enable tracemalloc to get the object allocation traceback
Данные, возвращаемые функцие get_id_object_by_name: {'files': [{'id': '345245634', 'name': 'main-log-1', 'mimeType': 'text/plain'}]}
DEBUG:google_drive.uploader:Получен id файла main-log-1 в папке с id 'test_folder'.
.
----------------------------------------------------------------------
Ran 1 test in 0.026s
OK