导入时调用了模拟函数
我有一个模块需要测试,这个模块在导入时会调用一个函数,但出于各种原因我不能直接调用这个函数。所以我在模拟这个函数,但即使是模拟它也会触发导入。
比如,我正在测试的文件是 mod1.py,内容大概是这样的:
import os
def bar():
return 'foo'
def dont_call():
os.listdir("C:\\tmp")
dont_call()
而我的测试代码看起来像这样:
import mock
@mock.patch("mod1.dont_call")
def test_mod1(mock_dont_call):
import mod1
assert mod1.bar()=='foo'
if __name__=="__main__":
test_mod1()
问题是 os.listdir 这个函数被调用了。
我不能修改 mod1,那我该怎么办呢?
我使用的是 python2.7。
为了让你更明白,我正在测试一个在导入时会打开数据库连接的模块,我对此并不赞同,但我能理解这样做的原因。不幸的是,我在我的测试机器上无法访问这个数据库。
3 个回答
0
检查你的目录
$tree.
test_shot/
├── mod1.py
├── __pycache__
│ └── mod1.cpython-310.pyc
└── test.py
下面的代码对我来说运行得很好。
mod1.py
import os
def bar():
return 'foo'
def dont_call():
os.listdir(".")
def call_this():
print('called this')
call_this()
dont_call()
test.py
import mock
@mock.patch("mod1.dont_call")
def test_mod1(mock_dont_call):
import mod1
assert mod1.bar()=='foo'
if __name__=="__main__":
test_mod1()
这是输出结果:
$cd test_shot
$python3 test.py
called this
2
如果你想让代码在导入时“不要”被执行,可以把它放在下面的条件里:
在 mod1.py 文件中,做如下操作:
if __name__=="__main__":
dont_call()
这是因为,默认情况下,当你导入一个 Python 模块时,里面的所有代码都会被执行。通过添加上面的条件,你明确表示只有在这个文件作为脚本运行时,才会调用 dont_call(),而在其他模块导入它时则不会调用。
0
我找到的解决办法是模拟一下dont_call这个函数所调用的内容,这样我就得到了类似下面的东西:
import mock
@mock.patch("os.listdir")
def test_mod1(mock_dont_call):
import mod1
assert mod1.bar()=='foo'
if __name__=="__main__":
test_mod1()