Python Mock Patch 为被测子模块和被测子模块中的每个其他导入子模块打补丁
Python Mock Patch patches a used module for submodule under test and every other imported submodule in the submodule under test
抱歉,标题有点混乱,但很难找到清晰的标题。
我的问题:
我有一个正在测试的子模块,我们称它为 backend
。我在 backend
中使用 random.choice
。我在我的测试中对其进行了修补并且有效。它已打补丁。 backend
导入 pymongo
来做一些数据库工作,pymongo 也使用 random.choice
在 core.py
.
中选择正确的服务器
不知何故,我的 backend.random.choice
补丁也被用于 backend.pymongo.random.choice
。我不确定为什么。这是正确的行为吗?如果是,有什么方法可以解决这个问题?最好不要更改后端和 pymongo 中的任何代码,但仅在我的测试中。
其他调查:
我设置了一个小测试结构,看看它是否与我的项目相关或一般情况。
我创建了一些模块:
bar/bar.py
import random
def do_some_other_something():
return random.choice([10])
foo/foo.py
import random
from bar.bar import do_some_other_something
def do_something():
return random.choice([1])
def do_something_else():
return do_some_other_something()
还有一个测试用例:
from foo.foo import do_something, do_something_else
from unittest import mock
assert(do_something() == 1) # check
assert(do_something_else() == 10) # check
with mock.patch("foo.foo.random.choice") as mock_random_choice:
assert (do_something() != 1) # check (mocked as expected)
assert (do_something_else() == 10) # assertion! also mocked
所以我对此真的很困惑。我明确地嘲笑了 foo.foo 的 random.choice 而不是 bar.bar 的。那为什么会这样呢?故意的?有办法解决这个问题吗?
谢谢!
程序中只有一个 random
模块。当 foo.foo
和 bar.bar
都 import random
时,它们 共享 random
模块。在 random
模块上修补 choice
函数会修改程序每个部分使用的一个 random
模块,包括 foo.foo
和 bar.bar
.
不是修补 foo.foo.random.choice
,而是修补 foo.foo.random
。这会替换 foo.foo
对 random
模块的引用,但不会替换 bar.bar
的引用。 bar.bar
将继续访问真正的 random
模块,但 foo.foo
将看到模拟 random
.
抱歉,标题有点混乱,但很难找到清晰的标题。
我的问题:
我有一个正在测试的子模块,我们称它为 backend
。我在 backend
中使用 random.choice
。我在我的测试中对其进行了修补并且有效。它已打补丁。 backend
导入 pymongo
来做一些数据库工作,pymongo 也使用 random.choice
在 core.py
.
不知何故,我的 backend.random.choice
补丁也被用于 backend.pymongo.random.choice
。我不确定为什么。这是正确的行为吗?如果是,有什么方法可以解决这个问题?最好不要更改后端和 pymongo 中的任何代码,但仅在我的测试中。
其他调查:
我设置了一个小测试结构,看看它是否与我的项目相关或一般情况。
我创建了一些模块:
bar/bar.py
import random
def do_some_other_something():
return random.choice([10])
foo/foo.py
import random
from bar.bar import do_some_other_something
def do_something():
return random.choice([1])
def do_something_else():
return do_some_other_something()
还有一个测试用例:
from foo.foo import do_something, do_something_else
from unittest import mock
assert(do_something() == 1) # check
assert(do_something_else() == 10) # check
with mock.patch("foo.foo.random.choice") as mock_random_choice:
assert (do_something() != 1) # check (mocked as expected)
assert (do_something_else() == 10) # assertion! also mocked
所以我对此真的很困惑。我明确地嘲笑了 foo.foo 的 random.choice 而不是 bar.bar 的。那为什么会这样呢?故意的?有办法解决这个问题吗?
谢谢!
程序中只有一个 random
模块。当 foo.foo
和 bar.bar
都 import random
时,它们 共享 random
模块。在 random
模块上修补 choice
函数会修改程序每个部分使用的一个 random
模块,包括 foo.foo
和 bar.bar
.
不是修补 foo.foo.random.choice
,而是修补 foo.foo.random
。这会替换 foo.foo
对 random
模块的引用,但不会替换 bar.bar
的引用。 bar.bar
将继续访问真正的 random
模块,但 foo.foo
将看到模拟 random
.