我正在尝试使用 pytest 和 mocker 来测试我正在编写的 python 包。这是我的 repo 的概要(假设包名为hoopla)
hoopla
hoopla |- library |- __init__.py |- general |- exceptions |- bourhaha |- tests |- __init__.py |- test_brouhaha
里面general.py有一些可以通过包和包内文件使用的函数。例如:
general.py
validate_email_exists()
brouhaha.py
create_username()
在测试函数时,test_brouhaha.py我想在它调用外部系统时模拟调用。 当我尝试使用 pytest 和 pytst-mock 模拟此调用时,出现错误“无模块…”(见下文)。validate_email_exists()``create_username()
test_brouhaha.py
validate_email_exists()``create_username()
# 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()函数使用的路径上。正确的路径是:
patch()
# CORRECT PATCHING mock_email_exists = mocker.patch("library.bourhaha.validate_email_exists")
请参阅文档中的修补位置patch()以了解有关正确使用的其他详细信息。
在您的情况下,文件general.py定义了函数validate_email_exists,但文件bourhaha.py执行import指令:
validate_email_exists
bourhaha.py
import
from .general import validate_email_exists
因此它会validate_email_exists在其命名空间中创建一个名称。您必须更改此名称指向的对象。使用您patch()已在定义对象的地方更改了该对象。
在您的代码中,您将 设置为return_value。此时您还必须更改指令,因为函数返回时函数会返回。mock_email_exists``False``assert``create_username()``False``validate_email_exists()``False
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完美。