#python #unit-testing #module #mocking #python-import
Вопрос:
Я пишу модульный тест для некоторого кода, и в коде, который я не могу изменить, есть этот вызов:
aps = firebase_admin.messaging.Aps( alert=None, content_available=True, sound="default", custom_data={ "title": title, "body": message, "notification_id": notification_id, "action_key": action_key } )
Я не хочу, чтобы что-то действительно происходило на стороне Firebase во время теста, но мне нужно убедиться, что блок кода, в котором находится этот вызов, будет выполнен. Поэтому я высмеял этот модуль вместе с некоторыми другими в своих файлах модульного тестирования:
firebase_admin_module = __import__('tests.mock_firebase_admin') sys.modules['firebase_admin'] = firebase_admin_module sys.modules['firebase_admin.credentials'] = __import__('tests.mock_firebase_admin.credentials') setattr(firebase_admin_module, 'credentials', __import__('tests.mock_firebase_admin.credentials')) sys.modules['firebase_admin.messaging'] = __import__('tests.mock_firebase_admin.messaging') setattr(firebase_admin_module, 'messaging', __import__('tests.mock_firebase_admin.messaging')) sys.modules['firebase_admin._apps'] = __import__('tests.mock_firebase_admin._apps') setattr(firebase_admin_module, '_apps', __import__('tests.mock_firebase_admin._apps')) sys.modules['firebase_admin.messaging.Aps'] = __import__('tests.mock_firebase_admin.aps') setattr(firebase_admin_module.messaging, 'Aps', __import__('tests.mock_firebase_admin.aps'))
Вот содержимое моего каталога mock_firebase_admin:
$ tree mock_firebase_admin mock_firebase_admin ├── __init__.py # empty file ├── _apps.py ├── aps.py # Aps class is defined here ├── credentials.py ├── firebase_singleton.py └── messaging.py # The same Aps class is also defined here
Вот мой макет класса Aps:
class Aps(): def __init__(self, alert=None, content_available=True, sound="default", custom_data={}): print("In Aps consturctor") return {}
Проблема в том, что вызов firebase_admin.messaging.Aps(...)
завершается ошибкой с этой ошибкой:
'module' object is not callable
Что я пробовал до сих пор:
Замена Aps()
класса Aps(...)
функцией в обоих файлах выглядит следующим образом:
def Aps(self, alert=None, content_available=True, sound="default", custom_data={}): print("In Aps function") pass
That changed nothing, the same error persists.
Commenting out the line sys.modules['firebase_admin.messaging.Aps'] = __import__('tests.mock_firebase_admin.aps')
. Changes nothing, the same error persists.
Commenting out the line setattr(firebase_admin_module.messaging, 'Aps', __import__('tests.mock_firebase_admin.aps'))
. Then the error changes to 'module' object has no attribute 'Aps'
.
Changing the line setattr(firebase_admin_module.messaging, 'Aps', __import__('tests.mock_firebase_admin.aps'))
to setattr(firebase_admin_module.messaging, 'Aps', __import__('tests.mock_firebase_admin.aps.Aps'))
. Results in the following traceback:
... tests/utils.py:28: in lt;modulegt; setattr(firebase_admin_module.messaging, 'Aps', __import__('tests.mock_firebase_admin.aps.Aps')) E ImportError: No module named Aps
Что я делаю не так? Как я могу исправить это так, чтобы вызов firebase_admin.messaging.Aps(...)
вызывал класс в моем макетном модуле, а не сам модуль?