Я пытаюсь использовать pytest и mocker для тестирования пакета Python, который я пишу. Это схема моего репо (при условии, что пакет называется hoopla
)
hoopla
|- library
|- __init__.py
|- general
|- exceptions
|- bourhaha
|- tests
|- __init__.py
|- test_brouhaha
Внутри general.py
у меня есть некоторые функции, которые можно использовать через пакет, а также файлы внутри пакета. Например:
general.py
содержит функцию validate_email_exists()
brouhaha.py
содержит функцию с именем create_username()
, которая вызывает функцию validate_email_exists()
.Внутри test_brouhaha.py
я хочу издеваться над вызовом validate_email_exists()
при тестировании функции create_username()
, когда она обращается к внешней системе.
Когда я пытаюсь издеваться над этим вызовом, используя pytest и pytst-mock, я получаю сообщение об ошибке «Нет модуля...» (см. ниже).
# general.py
def validate_email_exists(email):
return True
# bourhaha.py
from .general import validate_email_exists
def create_username(email):
if not validate_email_exists(email):
return False
# create usename
return True
# test_bourhaha.py
from library.bourhaha import *
def test_create_username(mocker):
mock_email_exists = mocker.patch("library.bourhaha.general.validate_email_exists") # causes error
---
mock_email_exists = mocker.patch("library.general.validate_email_exists") # causes error
mock_email_exists.return_value = False
assert create_username("test") # Fails because value of validate_email_exists return True
---
В моем коде я изначально издевался над
mock_email_exists = mocker.patch("library.brouhaha.general.validate_email_exists")
mock_email_exists.return_value = False
И это выдает ошибку
ModuleNotFoundError: No module named 'library.brouhaha.general'; 'library.brouhaha' is not a package
Когда я пытаюсь
mock_email_exists = mocker.patch("library.general.validate_email_exists")
mock_email_exists.return_value = False
Ошибки нет, однако тест завершается неудачно, потому что функция возвращает True
Проблема заключается в пути, используемом функцией patch()
. Правильный путь:
# CORRECT PATCHING
mock_email_exists = mocker.patch("library.bourhaha.validate_email_exists")
Таким образом, вы можете установить return_value
из mock_email_exists
на False
, как вы правильно делаете в своем тесте. Но в этот момент вам нужно изменить инструкцию assert
, потому что функция create_username()
возвращает False
, когда функция validate_email_exists()
возвращает False
.
Итак, правильная тестовая функция:
from library.bourhaha import *
def test_create_username(mocker):
# WATCH to the path = 'library.bourhaha.validate_email_exists'
mock_email_exists = mocker.patch("library.bourhaha.validate_email_exists")
mock_email_exists.return_value = False
# I have change the assert test (assert ---> assert not)
assert not create_username("test")
Ваши модули general.py
и bourhaha.py
идеальны.
Возможно я упустил какой-то момент, но иногда пишется
brouhaha
, иногдаbourhaha
.