I'am facing a problem when testing a function that reads the first line of a file and raises an Exception
when the path of the file doesn't exist.
Current code:
from unittest.mock import patch, mock_open
from pytest import raises
from os.path import exists
def read_from_file(file_path):
if not exists(file_path):
raise Exception("File does not exists!")
with open(file_path, "r") as f:
return f.read().splitlines()[0]
@patch("builtins.open", new_callable=mock_open, read_data="Correct string\nWrong string\nWrong string")
@patch("os.path.exists", return_value=True)
def test_read_file_and_returns_the_correct_string_with_multiple_lines(mock_os, mock_file):
result = read_from_file("xyz")
mock_file.assert_called_once_with("xyz", "r")
assert result == "Correct string"
@patch("builtins.open", new_callable=mock_open, read_data="Correct string")
@patch("os.path.exists", return_value=False)
def test_throws_exception_when_file_doesnt_exist(mock_os, mock_file):
with raises(Exception):
read_from_file("xyz")
The decorators @patch("os.path.exists", return_value=True)
and @patch("os.path.exists", return_value=False)
seems to have no effect in both tests.
How can I mock the existence of a file?
The error arises because the read_from_file
directly imports exists
from os.path
and uses it, but the mock targets os.path.exists
, which does not affect the direct import. Hence, the real function gets executed instead of the mock.
Change read_from_file
to this:
import os.path
def read_from_file(file_path):
if not os.path.exists(file_path):
raise Exception("File does not exist!")
with open(file_path, "r") as f:
return f.read().splitlines()[0]