假设我们有以下 Flask 视图函数要测试。具体来说,我们希望在create_foo()
写入文件系统时模拟它。
# proj_root/some_project/views.py
from some_project import APP
from some_project.libraries.foo import create_foo
@APP.route('/run', methods=['POST']
def run():
bar = create_foo()
return 'Running'
现在我们想为run()
编写一个单元测试,调用create_foo()
mocked 以避免创建不必要的文件。
# proj_root/tests/test_views.py
from some_project import some_project
@pytest.fixture
def client():
some_project.APP.config['TESTING'] = True
with some_project.APP.test_client() as client:
yield client
def test_run(client, monkeypatch):
monkeypatch.setattr('some_project.libraries.foo.create_foo', lambda: None)
response = client.post('/run')
assert b'Running' in response.data
似乎这种方法即使适用于命名的create_foo
导入。测试都通过了,但是create_foo
的原始代码显然是在执行的,因为每次运行测试套件时都会在文件系统中创建一个新文件。我错过了什么?根据一些相关问题,我怀疑这与命名的导入有关,但我不确定。
正确的猴子补丁是:
monkeypatch.setattr('some_project.views.create_foo', lambda: None)
这里很好地解释了其中的原因。