How do I reproduce OSError so that I can know that my exception works?
def write_file():
try:
with open('file.txt', "w+") as f:
f.write("sth")
f.close()
except OSError as e:
logging.error("OSError occured")
I want to write unit test for the funtion write_file()
using pytest. How do I mock the OSError
?
You'd have to mock out the open()
call. You could do so with standard library unittest.mock.patch()
function, or with the pytest
monkeypatch
fixture; I personally prefer to use the standard library here:
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")]
The mock.patch()
context manager setup places a mocked open
object in the module_under_test
global namespace, masking the built-in open()
function. Setting the side_effect
attribute to an exception ensures that calling the mocked object will raise that exception.
Mocking out open()
is far easier than trying to create the exact filesystem circumstances in which the built-in open()
function would raise an exception. Moreover, you are testing how your own code is handling OSError
correctly, not if open()
is working as designed.
Some side notes:
f.close()
; you are using the open file as a context manager (with ... as f:
) and so it is closed automatically, whatever happens in the with
block.except OSError as e:
when you don't intent to use the e
reference to the exception; drop the as e
part.logging.exception()
function, then the exception and the full traceback are captured in the log, as an ERROR
level message.def write_file():
try:
with open('file.txt', "w+") as f:
f.write("sth")
except OSError:
logging.exception("Failed to write to file.txt")