如何Mock文件存在性与文件打开,处理路径不存在时的异常?
解决Mock文件存在性失效的问题
问题出在你导入exists的方式和patch的目标不匹配:
- 你代码里用
from os.path import exists把函数直接导入到了当前模块的命名空间,相当于在当前模块里创建了一个指向os.path.exists的引用 - 而你用
@patch("os.path.exists")是去修改原模块的exists,但你的函数调用的是当前模块里的那个引用,所以mock根本没作用
修正方法
把patch的目标改成当前模块中的exists:
- 如果测试代码和
read_from_file在同一个文件里,用@patch("__main__.exists") - 如果函数在单独的模块(比如叫
file_utils.py),就用@patch("file_utils.exists")
修正后的完整代码:
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("__main__.exists", return_value=True) # 修改为当前模块的exists 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("__main__.exists", return_value=False) # 同样修改这里 def test_throws_exception_when_file_doesnt_exist(mock_os, mock_file): with raises(Exception): read_from_file("xyz")
这样修改后,两个测试里的mock就会正确生效:
- 第一个测试中
exists返回True,函数会执行文件读取逻辑,验证首行内容 - 第二个测试中
exists返回False,函数会抛出预期的异常
内容的提问来源于stack exchange,提问作者Luiz
相关产品推荐
相关产品推荐

