为了测试,我想在我的主模块中修补
time.sleep
(并声明它的调用),without在子模块中修补它。
但是,在我的模块中导入time
并在我的主模块(time.sleep
)中修补mocker.patch("main.time.sleep")
也会在所有子模块中模拟
time.sleep
(场景A)。sleep
中导入 time
并在我的主模块中修补 sleep
(mocker.patch("main.sleep")
) 模拟 sleep
only 在主模块中(场景 B,期望的结果)。
为什么?为什么进口会有所不同?为什么
time.sleep
首先在全球范围内被嘲笑?不应该只在它被查找的地方被嘲笑吗?
根据单元测试Where-To-Patch-Article“patch() 的工作原理是(暂时)将名称指向的对象更改为另一个名称”。
→ 那么,
sleep
中的方法 time
应该被两种场景中的所有模块替换吗?
此外,“你在查找对象的位置进行修补,这不一定与定义对象的位置相同”。
→ 所以也许
sleep
方法是 not 替换所有模块?
文章还说明了一个主模块
b
:
如果
SomeClass
从模块a
导入并且SomeClass()
在主模块b
中调用→SomeClass
在主模块中查找b
如果模块
a
被导入并且a.SomeClass()
在主模块中被调用b
→SomeClass
在模块中查找a
→ 这就是为什么
sleep
在场景 A 中被全局模拟而在场景 B 中被局部模拟的原因吗?但是,在这两种情况下,sleep
不只是对相同的 time.sleep
方法的引用吗?
根据this讨论,在不同模块中导入(例如)
time
意味着sharingtime
模块。并且在主模块中修补它的方法也为所有其他模块修补它。而在 main 中修补整个 time
模块只会改变 main 中 time
的 reference。
main.py:
import time
import module
def sleep_in_main():
time.sleep(1) # this is mocked
module.sleep_in_module()
模块.py:
import time
def sleep_in_module():
time.sleep(1) # this is also mocked
测试.py:
import main
def test(mocker):
sleep_mock = mocker.patch("main.time.sleep")
main.sleep_in_main()
assert sleep_mock.call_count == 1 # fails (is called twice)
main.py:
from time import sleep
import module
def sleep_in_main():
sleep(1) # this is mocked
module.sleep_in_module()
模块.py:
from time import sleep
def sleep_in_module():
sleep(1) # this is not mocked
测试.py:
import main
def test(mocker):
sleep_mock = mocker.patch("main.sleep")
main.sleep_in_main()
assert sleep_mock.call_count == 1 # passes