你必须嘲笑这个open()
电话。您可以使用标准库unittest.mock.patch()
函数或pytest
monkeypatch
夹具来执行此操作;我个人更喜欢在这里使用标准库:
import pytest
import logging
from unittest import mock
from module_under_test import write_file
def test_write_file_error(caplog):
caplog.clear()
with mock.patch("module_under_test.open") as mock_open:
mock_open.side_effect = OSError
write_file()
assert caplog.record_tuples == [("root", logging.ERROR, "OSError occured")]
mock.patch()
上下文管理器设置在全局命名空间中放置一个模拟open
对象module_under_test
,屏蔽内置open()
函数。将side_effect
属性设置为异常可确保调用模拟对象将引发该异常。
模拟open()
比尝试创建内置open()
函数会引发异常的确切文件系统环境要容易得多。此外,您正在测试您自己的代码如何正确处理OSError
,而不是是否open()
按设计工作。
一些旁注:
- 无需致电
f.close()
;您将打开的文件用作上下文管理器 ( ),因此无论块中发生什么,它都会自动with ... as f:
关闭。with
- 发生了正确的拼写(双r):-)
except OSError as e:
当你不打算使用e
对异常的引用时不要使用;放下as e
零件。
- 如果您使用该
logging.exception()
函数,则异常和完整的回溯将作为ERROR
级别消息捕获在日志中。
def write_file():
try:
with open('file.txt', "w+") as f:
f.write("sth")
except OSError:
logging.exception("Failed to write to file.txt")