我有一个大致如下所示的文件:
bar.py
from foo import foo # function that returns an int
from dog import Dog
dog_foo = 4 * foo()
my_dog = Dog(dog_foo)
...
我想测试
my_dog
对象是否已正确实例化为 foo()
乘以 4 的结果。这是一个单元测试,所以我试图避免测试 foo()
的内部结构。事实上,我想打补丁foo
,这样内部结构就不再重要了。
但是,一旦我将 bar 中的任何内容导入到我的测试中,实例化行就已经运行了。因此,我需要以某种方式导入修补块的内部。我到底应该在这里修补什么?
我尝试了这个,但似乎没有使用补丁:
with mock.patch("foo.foo") as mock_foo:
mock_foo.return_value = 5
from bar import my_dog
我也尝试过这个:
with mock.patch("bar.foo") as mock_foo:
mock_foo.return_value = 5
from bar import my_dog
这一定是可能的吧?我错过了什么?
对于其他发现此问题并且同样陷入困境的人,我想通了!
我正在使用 pytest,并且
bar.py
文件正在测试收集时执行。我有另一个测试文件,正在从 bar.py
导入值。为了收集测试,pytest 正在执行此导入。这意味着 bar.py
在测试收集时执行并且为 sys.modules 所知。因此,它不需要再次执行,只是返回已经计算的值而不是重新执行。
我通过重新加载模块而不是模拟上下文来解决这个问题。测试代码如下所示:
import sys
from importlib import reload
from unittest import mock
def test_my_dog:
with mock.patch("foo.foo") as mock_foo:
mock_foo.return_value = 5
reload(sys.modules.get('bar'))
from bar import my_dog
assert mock_foo.call_count == 1
assert my_dog.dog_foo == 20
reload(sys.modules.get('bar')) # This resets it for the next run.