Python 测试:使用带有 mock 和 io.StringIO 的假文件

2024-01-25

我正在尝试测试一些在文件上运行的代码,但我似乎无法理解如何使用真实文件替换mock and io.StringIO我的代码大致如下:

class CheckConfig(object):
    def __init__(self, config):
        self.config = self._check_input_data(config)

    def _check_input_data(self, data):
        if isinstance(data, list):
            return self._parse(data)
        elif os.path.isfile(data):
            with open(data) as f:
                return self._parse(f.readlines())

    def _parse(self, data):
        return data

我有一个类可以接受列表或文件,如果它是文件,它会打开它并将内容提取到列表中,然后对结果列表执行需要执行的操作。

我有一个工作测试如下:

def test_CheckConfig_with_file():
    config = 'config.txt'
    expected = parsed_file_data
    actual = CheckConfig(config).config
    assert expected == actual

我想替换对文件系统的调用。我尝试用以下内容替换该文件io.StringIO但我得到一个TypeError from os.path.isfile()因为它需要一个字符串、字节或整数。我也尝试过嘲笑isfile像这样的方法:

@mock.patch('mymodule.os.path')
def test_CheckConfig_with_file(mock_path):
    mock_path.isfile.return_value = True
    config = io.StringIO('data')
    expected = parsed_file_data
    actual = CheckConfig(config).config
    assert expected == actual

但我还是得到同样的结果TypeError as the _io.StringIO类型之前导致异常isfile有机会退货。

我怎样才能得到os.path.isfile当我传递一个假文件时返回 True?或者这是我应该更改代码的建议?


只是模拟两者os.path.isfile and the open()调用,并传入一个假文件名(毕竟,您不应该传入一个打开的文件)。

模拟库包含后者的实用程序:mock_open() https://docs.python.org/3/library/unittest.mock.html#mock-open:

@mock.patch('os.path.isfile')
def test_CheckConfig_with_file(mock_isfile):
    mock_isfile.return_value = True
    config_data = mock.mock_open(read_data='data')
    with mock.patch('mymodule.open', config_data) as mock_open:
        expected = parsed_file_data
        actual = CheckConfig('mocked/filename').config
        assert expected == actual

这导致if isinstance(data, list):测试为假(因为data是一个字符串),然后是elif os.path.isfile(data):返回True,以及open(data)调用以使用您的模拟数据mock_open() result.

您可以使用mock_open变量来断言open()被调用时使用了正确的数据(mock_open. assert_called_once_with('mocked/filename')例如)。

Demo:

>>> import os.path
>>> from unittest import mock
>>> class CheckConfig(object):
...     def __init__(self, config):
...         self.config = self._check_input_data(config)
...     def _check_input_data(self, data):
...         if isinstance(data, list):
...             return self._parse(data)
...         elif os.path.isfile(data):
...             with open(data) as f:
...                 return self._parse(f.readlines())
...     def _parse(self, data):
...         return data
...
>>> with mock.patch('os.path.isfile') as mock_isfile:
...     mock_isfile.return_value = True
...     config_data = mock.mock_open(read_data='line1\nline2\n')
...     with mock.patch('__main__.open', config_data) as mock_open:
...         actual = CheckConfig('mocked/filename').config
...
>>> actual
['line1\n', 'line2\n']
>>> mock_open.mock_calls
[call('mocked/filename'),
 call().__enter__(),
 call().readlines(),
 call().__exit__(None, None, None)]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 测试:使用带有 mock 和 io.StringIO 的假文件 的相关文章

随机推荐

  • android:screenOrientation="sensorPortrait" 不适用于 API +17

    我希望我的应用程序能够在纵向和反向纵向模式下工作 换句话说 我希望它能够在纵向模式下工作并使其可旋转 180 度 我正在使用以下代码
  • 如何使用实体框架生成并自动递增 Id

    Revised整个帖子 我正在尝试通过 Fiddler 发布以下 JSON POST 请求 Username Bob FirstName Foo LastName Bar Password 123 Headline Tuna 但是我收到这个
  • 服务层是否应该访问 HttpContext?

    我正在构建一个大致遵循存储库模式的应用程序 顶部有一个服务层 类似于 Conery 的 MVC Storefront 的早期版本 我需要实现一个返回除当前用户之外的所有用户的页面 我已经在存储库和服务层上有了 GetUsers 方法 所以问
  • 如何在不相关的类之间传递C++回调?

    在非升压项目中 我有一个类 它使用基于特定用户操作 按下 释放按钮 的计时器 我希望此类具有通用性 因此它需要回调用户定义的操作 TimerClass h typedef void timerCallback void Class Time
  • 您是否可以允许用户回复卡片而不让卡片及其回复文本出现在时间线中?

    当我有一个带有回复操作的捆绑包 也许单个时间线卡也会发生这种情况 并且用户执行该操作 例如 花生酱和果冻三明治 时 会出现一个新的时间线卡 其中黑色背景上有白色文本玻璃上写着 花生酱和果冻三明治 当查看游乐场时 会出现同一张卡片 用户的头像
  • 如何临时切换 AWS CLI 的配置文件?

    更新的答案 7 10 2021 对于 AWS CLI v1 请执行以下操作 export AWS DEFAULT PROFILE user2 对于 AWS CLI v2 以下内容将起作用 export AWS PROFILE user2 完
  • SQLALchemy动态filter_by

    我知道您可以通过提供来构建用于 SQLAlchemy 查询的动态过滤器 kwargs to filter by 例如 filters id 123456 amount 232 db session query Transaction fil
  • 简单使用 RSACryptoServiceProvider KeyPassword 失败

    我想用密码保护我的 RSA 私钥 谁不会 但以下 C 失败 SecureString pw new SecureString pw AppendChar x CspParameters prms new CspParameters prms
  • MySQL 批量插入或更新

    有没有办法批量执行查询 例如INSERT OR UPDATE在 MySQL 服务器上 INSERT IGNORE 不起作用 因为如果该字段已经存在 它将简单地忽略它并且不插入任何内容 REPLACE 不起作用 因为如果该字段已经存在 它将首
  • 将订阅的 Android 应用程序转移到另一个帐户

    据我所知 谷歌不允许将应用程序所有权通过应用程序订阅从一个开发者帐户转移到另一个开发者帐户 我一直在等待他们启用该功能 但到目前为止 该功能尚不可用 也没有预计到达时间 我有一个付费应用程序 其中包含应用程序内订阅 一家公司正在寻求收购我的
  • 泄漏:ByteBuf.release() 在被垃圾收集之前没有被调用。 Spring Reactor TcpServer

    我正在使用reactor core 1 1 0 RELEASE reactor net 1 1 0 RELEASE 正在使用netty all 4 0 18 Final reactor spring context 1 1 0 RELEAS
  • 如何修改 git post-update hook 以仅在一个(主)分支上激活?

    我在我的网络主机上设置了一个裸存储库 并从中克隆了一个存储库 只要将更改推送到裸存储库 该存储库就会更新 Web 主机上的克隆存储库本质上是 生产 它位于 public html 目录中 我非常严格地遵循了该网站上的说明 http www
  • 设置默认的 apache 虚拟主机

    除了选择它找到的第一个配置之外 还有其他更好的方法来设置默认的 apache 虚拟主机吗 我有一台包含许多域的服务器 其中只有一些域配置了 httpd 但默认的虚拟主机被切断 例如 aaa com 我真的希望它默认为 mmm com 吗 像
  • 已知起点和距离计算第二点

    使用纬度和经度值 A 点 我尝试计算另一个点 B 距离 A 点 X 米 距离 A 点 0 弧度 然后显示 B 点的纬度和经度值 示例 伪代码 PointA Lat x xxxx PointA Lng x xxxx Distance 3 Me
  • 如何在 Python 中打印 Unicode 字符代码?

    我想打印 unicode 的字符代码 而不是它在 Python 中表示的实际字形 例如 如果u是 unicode 字符列表 gt gt gt u 0 u u0103 gt gt gt print u 0 我想将字符代码输出为原始字符串 u
  • 设置 Github Commit RSS 源

    我正在尝试将我的 github 提交为 RSS feed 但到目前为止我还没有弄清楚 我知道私人提要可使用以下语法 https github com username atom token token 但这是用户的活动源 我想要我的一个项目
  • 如何使用 DynamoDB 进行基本聚合?

    dynamodb 是如何实现聚合的 Mongodb 和 couchbase 具有地图缩减支持 假设我们正在建立一个技术博客 用户可以在其中发布文章 并说文章可以被标记 user id 1235 name John article id 78
  • 在 R 中加载具有最新日期的文件[重复]

    这个问题在这里已经有答案了 假设我有一个文件想要在 R 中加载 让我们称之为file csv 将其加载到 R 中相当容易 不幸的是 在我的情况下 存在该文件的多个版本 并且每个文件都附加了一个日期 所以我的目录中真正拥有的是文件列表 例如
  • Gem::Ext::BuildError: 错误: 无法在 macOS Monterey 上构建 gem 本机扩展

    当我跑步时bundle install在我的 Rails 5 项目中 我在似乎具有本机扩展的 gem 上遇到了许多错误 以下是其中一个 gem 的输出顶部 Installing nio4r 1 2 1 with native extensi
  • Python 测试:使用带有 mock 和 io.StringIO 的假文件

    我正在尝试测试一些在文件上运行的代码 但我似乎无法理解如何使用真实文件替换mock and io StringIO我的代码大致如下 class CheckConfig object def init self config self con