模拟与 __init__.py 模块混淆
Mocking confused with __init__.py module
我目前正在尝试使用 mock 来测试包。当我使用 __init__.py
在不同的目录中构建我的 python 模块时,Mock 似乎不喜欢它
我的文件树如下:
.\pkg
|_ module
|_ __init__.py
|_ module.py
|_ tests
|_ __init__.py
|_ test_basic.py
当我尝试使用以下单元测试模拟 filesize 中的方法时:
@mock.patch('module.os')
def test_filesize(self, mock_os):
class file_info:
st_size = 1000
mock_os.path.isfile.return_value = True
mock_os.stat.return_value = file_info
output = self.response.file_size("filename")
我收到错误回溯:
======================================================================
ERROR: test_filesize (__main__.cl_test_build_search_url)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\mock\mock.py", line 1297, in patched
arg = patching.__enter__()
File "C:\Python36\lib\site-packages\mock\mock.py", line 1369, in __enter__
original, local = self.get_original()
File "C:\Python36\lib\site-packages\mock\mock.py", line 1343, in get_original
"%s does not have the attribute %r" % (target, name)
AttributeError: <module 'module' from 'C:\Users\username\work\open_source\pkg\module\__init__.py'> does not have the attribute 'os'
我已经在 module.py
中导入了 os 模块,但我认为它变得很混乱,因为 __init__.py
混淆了解释器?
我查看了可用的 mock.patch 个参数并且
@mock.patch('module.os', create = True)
允许代码 运行 但 os 根本不会被嘲笑,并且 os.path.isfile
和 os.stat
在 [=40] 期间不会被覆盖=] 时间.
尝试改变这个:
@mock.patch('module.os', create = True)
对此:
# module(directory) module(module.py)
@mock.patch('module.module.os', create = True)
我不擅长解释,这里是 mock.py
解释的摘要:
target
should be a string in the form 'package.module.ClassName'
. The
target
is imported and the specified object replaced with the new
object, so the target
must be importable from the environment you are
calling patch
from. The target is imported when the decorated function
is executed, not at decoration time.
我想对@Gang 的回答再补充一点,因为这让我很生气。由于上面的示例名称,这会有点混乱,但是...
上面的例子:
.\pkg
|_ module
|_ __init__.py
|_ module.py
|_ tests
|_ __init__.py
|_ test_basic.py
假设在 pkg.module.module
中你有一个名为 module
的 class(与 python 文件名相同)
module.py
from time import time
class module:
pass
在你的 pkg.module __init__.py
中你会做类似
from .module import module
__all__ = (
"module",
)
如果您想在 module.py
中修补 time
:
mock.patch("pkg.module.module.time", ...)
Mock 将通过 __init__.py
得到 confused/blocked 并给你一个像
这样的错误
E AttributeError: <class 'pkg.module.module.module'> does not have the attribute 'time'
我必须更改文件名或 class。或者甚至只是改变大小写,在上面的例子中。
from time import time
class Module:
pass
init.py
from .module import Module
__all__ = (
"Module",
)
我目前正在尝试使用 mock 来测试包。当我使用 __init__.py
我的文件树如下:
.\pkg
|_ module
|_ __init__.py
|_ module.py
|_ tests
|_ __init__.py
|_ test_basic.py
当我尝试使用以下单元测试模拟 filesize 中的方法时:
@mock.patch('module.os')
def test_filesize(self, mock_os):
class file_info:
st_size = 1000
mock_os.path.isfile.return_value = True
mock_os.stat.return_value = file_info
output = self.response.file_size("filename")
我收到错误回溯:
======================================================================
ERROR: test_filesize (__main__.cl_test_build_search_url)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\mock\mock.py", line 1297, in patched
arg = patching.__enter__()
File "C:\Python36\lib\site-packages\mock\mock.py", line 1369, in __enter__
original, local = self.get_original()
File "C:\Python36\lib\site-packages\mock\mock.py", line 1343, in get_original
"%s does not have the attribute %r" % (target, name)
AttributeError: <module 'module' from 'C:\Users\username\work\open_source\pkg\module\__init__.py'> does not have the attribute 'os'
我已经在 module.py
中导入了 os 模块,但我认为它变得很混乱,因为 __init__.py
混淆了解释器?
我查看了可用的 mock.patch 个参数并且
@mock.patch('module.os', create = True)
允许代码 运行 但 os 根本不会被嘲笑,并且 os.path.isfile
和 os.stat
在 [=40] 期间不会被覆盖=] 时间.
尝试改变这个:
@mock.patch('module.os', create = True)
对此:
# module(directory) module(module.py)
@mock.patch('module.module.os', create = True)
我不擅长解释,这里是 mock.py
解释的摘要:
target
should be a string in the form'package.module.ClassName'
. Thetarget
is imported and the specified object replaced with thenew
object, so thetarget
must be importable from the environment you are callingpatch
from. The target is imported when the decorated function is executed, not at decoration time.
我想对@Gang 的回答再补充一点,因为这让我很生气。由于上面的示例名称,这会有点混乱,但是...
上面的例子:
.\pkg
|_ module
|_ __init__.py
|_ module.py
|_ tests
|_ __init__.py
|_ test_basic.py
假设在 pkg.module.module
中你有一个名为 module
的 class(与 python 文件名相同)
module.py
from time import time
class module:
pass
在你的 pkg.module __init__.py
中你会做类似
from .module import module
__all__ = (
"module",
)
如果您想在 module.py
中修补 time
:
mock.patch("pkg.module.module.time", ...)
Mock 将通过 __init__.py
得到 confused/blocked 并给你一个像
E AttributeError: <class 'pkg.module.module.module'> does not have the attribute 'time'
我必须更改文件名或 class。或者甚至只是改变大小写,在上面的例子中。
from time import time
class Module:
pass
init.py
from .module import Module
__all__ = (
"Module",
)