你必须嘲笑这个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")