如何使用 pytest Monkeypatch 模拟两个连续的控制台输入

2023-12-14

如果第一个用户输入的答案是“n”,则模块“overwrite_file”(请参阅​​代码示例)会要求输入新文件名

在我的测试设置中,我使用两个连续的 Monkeypatch.setattr 调用来模拟输入。 如果我使用以下顺序,结果将是无限循环:

monkeypatch.setattr('builtins.input', lambda overwrite: "n")
monkeypatch.setattr('builtins.input', lambda new_name: new_filename)

第二个 Monkeypatch.setattr 调用被激活,并将“new.pkl”分配给变量覆盖。

如果我将 Monkeypatch 命令的顺序更改为:

monkeypatch.setattr('builtins.input', lambda new_name: new_filename)
monkeypatch.setattr('builtins.input', lambda overwrite: "n")

我收到断言错误,因为“n”被分配给变量 new_name 并创建了一个名为“n”的文件。

如何获得预期的测试功能?

解释器:Python 3.8

from os.path import exists, join, dirname
import pickle
import pytest


def overwrite_file(filename):
    # loop until overwrite existing file or input of a file name which does not exist
    dump_file = False
    while not dump_file:
        if exists(filename):
            overwrite = input(f"overwrite {filename} (y/n): ")
            if overwrite in ["y", "Y"]:
                dump_file = True
            if overwrite in ["n", "N"]:
                new_name = input("new filename: ")
                filename = join(dirname(filename), new_name)
        else:
            dump_file = True

    return filename


@pytest.fixture()
def pickle_test_env(tmpdir_factory):
    a_dir = tmpdir_factory.mktemp('src_dir')
    a_file = a_dir.join('already_there.pkl')
    with open(a_file, "wb") as f:
        pickle.dump({"C": 27.1, "S": -8.2, "T": 29.7}, f)
    return a_dir


def test_new_filename_if_file_exists(pickle_test_env, monkeypatch):
    """ is overwrite_file returning a valid new filename if filename exists
    and should not be overwritten? """
    filename = 'already_there.pkl'
    new_filename = 'new.pkl'
    assert exists(join(pickle_test_env, filename))
    monkeypatch.setattr('builtins.input', lambda new_name: new_filename)
    monkeypatch.setattr('builtins.input', lambda overwrite: "n")
    assert overwrite_file(join(pickle_test_env, filename)) == join(pickle_test_env, new_filename)

最后一个猴子补丁将战胜所有其他猴子补丁,所以input(f"overwrite {filename} (y/n): ")正在得到"n",也是如此input("new filename: ")。为了以正确的顺序提供所需的输入,我们可以对一个方法进行猴子修补,该方法将循环其响应

responses = iter(['n', new_filename])
monkeypatch.setattr('builtins.input', lambda msg: next(responses))

注意responses是一个迭代器对象——也就是说,调用next()它将返回列表中的下一个项目。如果input()被调用的次数多于列表中的项目数,StopIteration将被提高。可以提供可选的默认值,以避免StopIteration例外,并允许input()永远被称为:

next(responses, '\n')

可能有一种更干净的方式来提供标准输入input(),但我现在很茫然。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 pytest Monkeypatch 模拟两个连续的控制台输入 的相关文章

随机推荐

  • Google Sheets 脚本在从表单插入的行上插入时间戳?如何使用onChange检测插入的行?

    我正在尝试编写一个脚本 该脚本将在从表单 不是谷歌表单 插入 Google 工作表的行 第 23 列 上插入时间戳 它是其他一些供应商将数据发送到工作表并且不通过时间戳 我一直在尝试从示例中编写一些脚本 但似乎无法让它发挥作用 到目前为止我
  • 如何在失败的重新分配中释放 malloc

    我有这个结构 typedef struct person st char first name last name int id Date birthday pPerson Person 可以说我重新分配sizeof Person n 几次
  • 在不同的对象上调用闭包?

    假设我有这样的课程 class MyClass int myInt MyClass myInt this myInt myInt def myMethod print this myInt 我在某个地方有 def myClass1 new
  • JavaScript 中 0 毫秒的 setInterval() 行为

    在我的应用程序中 我发现一些 JavaScript 代码正在使用setInterval0 毫秒 如下所示 self setInterval myFunction 0 显然 这对我来说似乎不是一个好主意 谁能告诉我将会有什么行为setInte
  • 如何将比例平移应用到 DrawingContext?

    我有一个Canvas在 XAML 中应用比例转换 使用DrawingContext我在上面画线Canvas 我现在需要向屏幕添加文本 我认为使用格式化文本我可以应用翻译 但是格式化文本或DrawingContext接受RenderTrans
  • 通过cmd运行带引号的powershell命令

    我需要通过 CMD 运行 powershell 命令 我的命令是 Get WmiObject Class win32 pnpEntity Filter Name like ACPI Thermal Zone 1 GetDevicePrope
  • 使用 javascript/jquery 对 JSON 数据进行分组/排序

    我有一个 JSON 数据 我需要做一些类似 group by 的事情 我之前在这里问过这个问题 但我没有得到任何满意的答案 所以这次我想更深入地解释一下 首先 谁能解释一下两者之间的区别groupby and orderby在 javasc
  • 如何按帖子元素对帖子数组进行排序?

    我有一个应用程序 用户可以在其中搜索待售商品 我目前正在尝试添加功能 以便用户可以查看按价格从低到高排序的商品 用户点击排序按钮后 他们会看到另一个显示不同排序选项的视图控制器 第一个是 价格 从低到高 从低到高被点击后 我使用协议发回一个
  • Android Api 8. 从视图中获取 x 和 y,并在按钮上设置 x 和 y

    我正在使用 API 8 进行编码 我需要从视图中获取坐标 X 和 Y 并将它们设置为新按钮的坐标 我尝试了不同的方法但没有任何作用 setX 和 getX 方法仅适用于 api 级别 11 我需要一种方法在 API8 上执行此操作 这是我的
  • 将文本文件读入数组列表

    我对 Java 很陌生 所以我在解决这个问题时遇到了一些麻烦 所以基本上我有一个如下所示的文本文件 1 John false 2 Bob false 3 Audrey false 如何从文本文件的每一行创建一个 ArrayList 从文件中
  • 为一个小团队和多个并行项目设置 TFS

    我们有一个五人开发团队 将并行构建多个内部项目 经过研究 我发现最好创建一个团队项目 即使对于我们的情况也是如此 对吗 如果是这样 您能否建议如何为项目和时间表设置适当的迭代 TFS 问题 小团队 多个项目听起来与我的情况相似 但我似乎无法
  • 如何获取接口成员列表

    有没有办法获取接口成员列表 我了解 System Reflection MemberInfo 但它包括对象中的所有内容 而不仅仅是某个接口 这是程序 我不知道如何获得接口 因为它不是我写的 但它是 Ascom 标准的一部分 http asc
  • Android ExpandableListView - 寻找教程[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我正在尝试编写一个 And
  • Sveltekit Actions 返回乱码 json

    从 Sveltekit 操作返回的 json 是乱码 我期望这样的事情 foo bar foo2 bar2 但我得到的是这个 Array foo 1 foo2 2 bar bar2 对于嵌套数据来说 这更令人烦恼 这就是我发送的方式 con
  • 传入未定义的目的是什么?

    我注意到了jQuery以及相关的主题插件 例如jQuery UI pass undefined作为模块定义中使用的匿名函数的参数 如下所示 function undefined jQuery 另外 我注意到 jQuery 推荐的其他插件和
  • 如何以编程方式将类或伪类添加到 JavaFX 中的自定义控件?

    在JavaScript世界中 通常设置元素类来表示它的外观 后来由CSS定义 JavaFX 中也是这样吗 例如 如果我想将负值涂成红色怎么办 TableView细胞 我不会直接编码颜色 但为单元格分配了一些类 例如 负 然后将其着色为红色C
  • 创建我的第一个树枝扩展以向基本模板提供全局变量

    我需要用一些 HTML 代码填充一个变量 并使其可用于我的 base html twig 文件 为了实现这一点 我做了一个树枝扩展 这是我第一次使用树枝扩展 所以我不确定这是否是正确的做法 这是我到目前为止所拥有的 扩展代码 class G
  • 如何更改spark中的日志级别?

    我尝试了所有这些方法 但没有任何作用 在 log4j 文件中 log4j logger org OFF log4j rootCategory ERROR console log4j rootCategory OFF console 在代码中
  • wxpython面板全屏?

    我试图让我的程序的 top panel 仅进入全屏 我希望有一个按钮可以执行此操作 我面临的问题是我不知道如何使面板自行进入全屏而不强制整个使用 ShowFullscreen true 进入全屏的框架 我希望你可以帮助我 class top
  • 如何使用 pytest Monkeypatch 模拟两个连续的控制台输入

    如果第一个用户输入的答案是 n 则模块 overwrite file 请参阅 代码示例 会要求输入新文件名 在我的测试设置中 我使用两个连续的 Monkeypatch setattr 调用来模拟输入 如果我使用以下顺序 结果将是无限循环 m