Я бы хотел иметь возможность исправить магический атрибут.
Основной файл, который я хотел бы проверить, это FileUtil.py, содержащий определение класса FileUtil:
class FileUtil:
@logit(showArgs=True, showRetVal=True)
def exec_file_path(self) -> str:
"""
Get the full dir and file path we're executing from using __file__, or if not available (probably because you're using a Jupyter notebook)
use os.path.abspath.
"""
try:
logger.debug('exec_file_path is about to attempt accessing __file__.')
return __file__
except NameError as err:
logger.debug('Exception message: {msg}'.format(msg=err))
return abspath('')
У меня также есть локальный тест в mockTest.py,содержащий класс AltFileUtil. Чтобы определить, какой из них вызывается, fUtil создает экземпляр AltFileUtil, а gUtil создает экземпляр FileUtil.
В тестируемом методе используется __file__
, но, за исключением этого, используется absdir
.
from os.path import abspath
from unittest.mock import MagicMock, PropertyMock, patch
class AltFileUtil:
def exec_file_path(self) -> str:
"""
Get the full dir and file path we're executing from using __file__, or if not available (probably because you're using a Jupyter notebook)
use os.path.abspath.
"""
try:
return __file__
except NameError as err:
return abspath('')
fUtil = AltFileUtil()
print (f'Part 1. function returns: {fUtil.exec_file_path()}')
patches = ['__main__.AltFileUtil', 'mockTest.AltFileUtil', ]
for p in patches:
print (f'Using patch of {p}.')
with patch(p) as mockFUtil:
type(mockFUtil.return_value).__file__ = PropertyMock(return_value='mockfilename')
x = mockFUtil.exec_file_path()
try:
print (f'Success! Got {x.__file__}.')
except (ValueError, AttributeError, TypeError) as e:
print(f'Got a {type(e)} error: {e}')
from FileUtil import FileUtil
gUtil = FileUtil()
print (f'Part 2. Using function from FileUtil.py, which returns: {gUtil.exec_file_path()}')
patches = ['FileUtil.FileUtil', ]
for p in patches:
print (f'Using patch of {p}.')
with patch(p) as mockFUtil:
type(mockFUtil.return_value).__file__ = PropertyMock(return_value='mockfilename')
x = mockFUtil.exec_file_path()
try:
print (f'Success! Got {x.__file__}.')
except (ValueError, AttributeError, TypeError) as e:
print(f'Got a {type(e)} error: {e}')
Вывод
C:\Users\Owner\PycharmProjects\Utilities\venv\Scripts\python.exe C:/Users/Owner/.PyCharm2019.2/config/scratches/mockTest.py
Part 1. function returns: C:/Users/Owner/.PyCharm2019.2/config/scratches/mockTest.py
Using patch of __main__.AltFileUtil.
Got a <class 'AttributeError'> error: __file__
Using patch of mockTest.AltFileUtil.
Part 1. function returns: C:\Users\Owner\.PyCharm2019.2\config\scratches\mockTest.py
Using patch of __main__.AltFileUtil.
Got a <class 'AttributeError'> error: __file__
Using patch of mockTest.AltFileUtil.
Got a <class 'AttributeError'> error: __file__
Part 2. Using function from FileUtil.py, which returns: C:\Users\Owner\PycharmProjects\Utilities\FileUtil.py
Using patch of FileUtil.FileUtil.
Got a <class 'AttributeError'> error: __file__
Got a <class 'AttributeError'> error: __file__
Part 2. Using function from FileUtil.py, which returns: C:\Users\Owner\PycharmProjects\Utilities\FileUtil.py
Using patch of FileUtil.FileUtil.
2019-10-08 07:42:13,797 DEBUG Entering exec_file_path.
Got a <class 'AttributeError'> error: __file__
2019-10-08 07:42:13,797 DEBUG >> 0. <FileUtil.FileUtil object at 0x03721230>
2019-10-08 07:42:13,797 DEBUG exec_file_path is about to attempt accessing __file__.
2019-10-08 07:42:13,797 DEBUG >> Return value is C:\Users\Owner\PycharmProjects\Utilities\FileUtil.py.
2019-10-08 07:42:13,797 DEBUG Exiting exec_file_path.
2019-10-08 07:42:13,797 DEBUG Entering exec_file_path.
2019-10-08 07:42:13,797 DEBUG >> 0. <FileUtil.FileUtil object at 0x02E64050>
2019-10-08 07:42:13,797 DEBUG exec_file_path is about to attempt accessing __file__.
2019-10-08 07:42:13,797 DEBUG >> Return value is C:\Users\Owner\PycharmProjects\Utilities\FileUtil.py.
2019-10-08 07:42:13,797 DEBUG Exiting exec_file_path.
Process finished with exit code 0
Я думаю, он должен был дать мне mockfilename
вместо ошибки атрибута.