Unittest 模拟用 mock 读取 yaml 文件
Unittest simulate reading a yaml file with a mock
我尝试测试一个读取文件和 returns 文件内容的函数,或者 returns none 如果找不到文件。
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.isfile
和 open
。要修补打开,已经有一个特殊的模拟函数 mock_open,它使您可以设置模拟文件的内容。这意味着您不必模拟 yaml.load
,因为这将 return 模拟文件内容。这可能看起来像:
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)
在这种情况下,如果您传递一个有效的文件名,您将测试函数 return 的文件内容,如果您传递一个无效的文件名,则测试 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 的贡献者。
我尝试测试一个读取文件和 returns 文件内容的函数,或者 returns none 如果找不到文件。
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.isfile
和 open
。要修补打开,已经有一个特殊的模拟函数 mock_open,它使您可以设置模拟文件的内容。这意味着您不必模拟 yaml.load
,因为这将 return 模拟文件内容。这可能看起来像:
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)
在这种情况下,如果您传递一个有效的文件名,您将测试函数 return 的文件内容,如果您传递一个无效的文件名,则测试 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 的贡献者。