在同一模块中使用 unittest.mock 的补丁,通过“__main__.imported_obj”打补丁时得到 "does not have the attribute"
Using unittest.mock's patch in same module, getting "does not have the attribute" when patching via "__main__.imported_obj"
我有一个本来应该很简单的任务,但它让我困惑了一段时间。我正在尝试 patch
将对象导入当前模块。
根据对 Mock patching from/import statement in Python
的回答
我应该可以 patch("__main__.imported_obj")
。但是,这对我不起作用。请查看我下面的最小重现(我正在 运行 通过 pytest
进行测试):
最小复制
这是 运行 使用 Python 3.8.6.
from random import random
from unittest.mock import patch
import pytest
@pytest.fixture
def foo():
with patch("__main__.random"):
return
def test(foo) -> None:
pass
当我 运行 此代码使用 PyCharm 时,我得到一个 AttributeError
:
AttributeError: <module '__main__' from '/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm/_jb_pytest_runner.py'> does not have the attribute 'random'
此外,当我在 with patch
之前的行中进入调试器模式时,我看到属性 __main__
未定义。我不确定是否需要为 patch
定义它来发挥它的魔力。
注意:我知道我可以使用 patch.object
,而且它变得容易多了。但是,我想弄清楚如何在这个问题中使用 patch
。
研究
这个问题是相关的,因为它既是类似的错误消息又是用例。他们的解决方案是使用 builtins
而不是 __main__
,但那是因为他们试图 patch
内置函数 (open
).
您假设测试 运行 所在的模块是 __main__
,但只有通过 main
调用时才会出现这种情况。如果您使用 unittest
,通常就是这种情况。使用 pytest,测试存在于它们定义的模块中。
您必须修补当前模块,其名称可通过 __name__
访问,而不是假定特定的模块名称:
from random import random
from unittest.mock import patch
import pytest
@pytest.fixture
def foo():
with patch(__name__ + ".random"):
yield
我有一个本来应该很简单的任务,但它让我困惑了一段时间。我正在尝试 patch
将对象导入当前模块。
根据对 Mock patching from/import statement in Python
的回答我应该可以 patch("__main__.imported_obj")
。但是,这对我不起作用。请查看我下面的最小重现(我正在 运行 通过 pytest
进行测试):
最小复制
这是 运行 使用 Python 3.8.6.
from random import random
from unittest.mock import patch
import pytest
@pytest.fixture
def foo():
with patch("__main__.random"):
return
def test(foo) -> None:
pass
当我 运行 此代码使用 PyCharm 时,我得到一个 AttributeError
:
AttributeError: <module '__main__' from '/Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm/_jb_pytest_runner.py'> does not have the attribute 'random'
此外,当我在 with patch
之前的行中进入调试器模式时,我看到属性 __main__
未定义。我不确定是否需要为 patch
定义它来发挥它的魔力。
注意:我知道我可以使用 patch.object
,而且它变得容易多了。但是,我想弄清楚如何在这个问题中使用 patch
。
研究
这个问题是相关的,因为它既是类似的错误消息又是用例。他们的解决方案是使用 builtins
而不是 __main__
,但那是因为他们试图 patch
内置函数 (open
).
您假设测试 运行 所在的模块是 __main__
,但只有通过 main
调用时才会出现这种情况。如果您使用 unittest
,通常就是这种情况。使用 pytest,测试存在于它们定义的模块中。
您必须修补当前模块,其名称可通过 __name__
访问,而不是假定特定的模块名称:
from random import random
from unittest.mock import patch
import pytest
@pytest.fixture
def foo():
with patch(__name__ + ".random"):
yield