python - Unittest 用mock模拟读取yaml文件

标签 python python-unittest python-unittest.mock

我尝试测试一个读取文件并返回文件内容的函数,如果找不到文件则不返回任何内容。

def read_yaml_from_cwd(file: str) -> Dict:
    """[reads a yaml file from current working directory]
    Args:
        file ([type]): [.yaml or .yml file]
    Returns:
        [type]: [Dictionary]
    """
    path = os.path.join(Path.cwd().resolve(), file)
    if os.path.isfile(path):
        with open(path) as f:
            content = yaml.load(f, Loader=SafeLoader)
            return content
    else:
        return None

这是我的测试:

from unittest import mock, TestCase
from project import fs

class TextExamples(TestCase):

    def test_read_yaml_from_cwd():
        with mock.patch('os.listdir') as mocked_listdir:
            mocked_listdir.return_value = ['test-config.yml']
            val = fs.read_yaml_from_cwd("false-config.yml")
            assert val == None
            val2 = fs.read_yaml_from_cwd("false-config.yml")
            assert val2 != None

我想我从根本上做错了这些测试和这些模拟的作用。有人可以帮我解决这个问题吗?

最佳答案

测试这一点的一种可能性是修补os.path.isfileopen。要打补丁,已经有一个特殊的mock函数了,mock_open ,这使您可以设置模拟文件的内容。这意味着您不必模拟 yaml.load,因为这将返回模拟的文件内容。这可能看起来像:

from unittest import mock, TestCase
from unittest.mock import mock_open

class YamlTest(TestCase):

    @mock.patch("builtins.open", mock_open(read_data="data"))
    @mock.patch("os.path.isfile")
    def test_read_yaml_from_cwd(self, patched_isfile):
        # valid file case
        patched_isfile.return_value = True
        result = read_yaml_from_cwd("some_file.yaml")
        self.assertEqual("data", result)

        # invalid file case
        patched_isfile.return_value = False
        result = read_yaml_from_cwd("some_file.yaml")
        self.assertEqual(None, result)

在本例中,您测试如果传递有效的文件名,该函数是否返回文件内容;如果传递无效的文件名,则返回“None”,这可能就是您想要在此处测试的全部内容。

为了完整起见,并且因为我在评论中提到了它:使用 pyfakefs相反,会用假文件系统替换文件系统,您可以像真实文件系统一样处理它,在这种情况下,它可能看起来像:

from pyfakefs import fake_filesystem_unittest

class YamlTest(fake_filesystem_unittest.TestCase):

    def setUp(self) -> None:
        self.setUpPyfakefs()
        self.fs.create_file("some_file.yaml", contents="data")

    def test_read_yaml_from_cwd(self):
        # valid file case
        result = read_yaml_from_cwd("some_file.yaml")
        self.assertEqual("data", result)

        # invalid file case
        result = read_yaml_from_cwd("non_existing.yaml")
        self.assertEqual(None, result)

如果您有许多与文件系统相关的测试,这是有意义的,但在您的情况下,这可能有点过头了。

免责声明:我是 pyfakefs 的贡献者。

关于python - Unittest 用mock模拟读取yaml文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70136213/

相关文章:

python - 使用装饰器补丁在 Python 中模拟类

python - 模拟类方法并将 self 参数传递给 Mock 的副作用

python - hamcrest.contains_inanyorder 的几乎无用的断言输出应用于 unittest.mock.Mock.mock_calls

python - 具有对称列和索引(行)标签的 Pandas Dataframe

python - 我的最长公共(public)子序列 python 中的逻辑错误

python - pytest:如何获取从模拟类返回的(模拟)实例?

python - 无法使用 unittest 修补由测试类实例化的类

unit-testing - 单元测试: How can you set attributes in a class

python - 导入模块中的可变对象

python - pyodbc UPDATE 抛出异常