当前位置: 首页 > 面试题库 >

自定义unittest.mock.mock_open以进行迭代

阎阳
2023-03-14
问题内容

我应该如何自定义unittest.mock.mock_open来处理此代码?

file: impexpdemo.py
def import_register(register_fn):
    with open(register_fn) as f:
        return [line for line in f]

我第一次尝试read_data

class TestByteOrderMark1(unittest.TestCase):
    REGISTER_FN = 'test_dummy_path'
    TEST_TEXT = ['test text 1\n', 'test text 2\n']

    def test_byte_order_mark_absent(self):
        m = unittest.mock.mock_open(read_data=self.TEST_TEXT)
        with unittest.mock.patch('builtins.open', m):
            result = impexpdemo.import_register(self.REGISTER_FN)
            self.assertEqual(result, self.TEST_TEXT)

这失败了,大概是因为代码不使用read,readline或readlines。unittest.mock.mock_open的文档说:“
read_data是一个字符串,供文件句柄的read(),readline()和readlines()方法返回。对这些方法的调用将从read_data中获取数据,直到耗尽为止这些方法的模拟非常简单。如果您需要更多控制要提供给测试代码的数据,则需要为您自己定制此模拟。read_data默认为空字符串。”

由于文件没有给出暗示什么样的定制将需要我试过return_valueside_effect。两者都不起作用。

class TestByteOrderMark2(unittest.TestCase):
    REGISTER_FN = 'test_dummy_path'
    TEST_TEXT = ['test text 1\n', 'test text 2\n']

    def test_byte_order_mark_absent(self):
        m = unittest.mock.mock_open()
        m().side_effect = self.TEST_TEXT
        with unittest.mock.patch('builtins.open', m):
            result = impexpdemo.import_register(self.REGISTER_FN)
            self.assertEqual(result, self.TEST_TEXT)

问题答案:

mock_open()对象确实不实现迭代

如果未将文件对象用作上下文管理器,则可以使用:

m = unittest.mock.MagicMock(name='open', spec=open)
m.return_value = iter(self.TEST_TEXT)

with unittest.mock.patch('builtins.open', m):

现在open()返回一个迭代器,可以像文件对象一样直接对其进行迭代,并且还可以使用next()。但是,它不能用作上下文管理器。

您可以将其与结合起来,mock_open()然后在返回值上提供__iter__and__next__方法,并获得额外的好处,这mock_open()也增加了用作上下文管理器的先决条件:

# Note: read_data must be a string!
m = unittest.mock.mock_open(read_data=''.join(self.TEST_TEXT))
m.return_value.__iter__ = lambda self: self
m.return_value.__next__ = lambda self: next(iter(self.readline, ''))

这里的返回值是MagicMockfile对象(Python
2)或内存文件对象(Python 3)中指定的对象,但是只有readwrite__enter__方法已存入。

上述方法不工作在Python 2,因为一个)的Python
2预计next存在,不__next__和b)next不被视为在模拟(这是正确的)的特殊方法,所以即使你重新命名__next__next在上述示例中的
类型 的返回值将没有next方法。在 大多数 情况下,使文件对象产生 可迭代的, 而不是使用以下代码进行迭代就足够了:

# Python 2!
m = mock.mock_open(read_data=''.join(self.TEST_TEXT))
m.return_value.__iter__ = lambda self: iter(self.readline, '')

iter(fileobj)然后,任何使用的代码都将起作用(包括for循环)。

Python跟踪器中存在一个开放的问题,旨在弥补这一差距。



 类似资料:
  • 本文向大家介绍python进阶之自定义可迭代的类,包括了python进阶之自定义可迭代的类的使用技巧和注意事项,需要的朋友参考一下 自定义可迭代的类 列表可以获取列表的长度,然后使用变量i对列表索引进行循环,也可以获取集合的所有元素,且容易理解。没错,使用列表的代码是容易理解,也很好操作,但这是要付出代价的。列表之所以可以用索引来快速定位其中的任何一个元素,是因为列表是一下子将所有的数据都装载在内

  • hyperf/process 可以添加一个用户自定义的工作进程,此函数通常用于创建一个特殊的工作进程,用于监控、上报或者其他特殊的任务。在 Server 启动时会自动创建进程,并执行指定的子进程函数,进程意外退出时,Server 会重新拉起进程。 创建一个自定义进程 在任意位置实现一个继承 Hyperf\Process\AbstractProcess 的子类,并实现接口方法 handle(): v

  • 问题内容: 目标是针对存储在结构数组中的某些值自定义图钉颜色。 通过这里的一些帮助,我实现了以下viewForAnnotation委托方法,该方法很好地基于结构数据数组的大小在循环中迭代调用此委托方法。因此,如果我要将所有引脚设置为一种颜色(例如,紫色)(这是下面代码中的注释行),则可以使用。 问题是当我放入一个开关以根据数组中的值设置颜色时,它会通过此代码,但不遵守任何大小写值来将其设置为备用颜

  • 问题内容: 我正在使用ElasticSearch 2.4.2(通过Java的HibernateSearch 5.7.1.Final)。 我对字符串排序有问题。我的应用程序的语言带有变音符号,它们具有特定的字母顺序。例如,直接在after之后,在after之后,等等。因此,您应该对字符串进行如下排序: ElasticSearch首先按典型字母排序,然后将所有奇怪的字母移到最后: 我可以为Elasti

  • 问题内容: 我担心给出的文件和目录的顺序。如果我有这些目录,,,,,,,,,,,,,什么是输出列表的顺序? 它是按数值排序的吗? 或按ASCII值排序,如? 此外,如何获得特定的排序? 问题答案: 用途。这是的文档字符串: listdir(路径)-> list_of_strings 返回一个列表,其中包含目录中条目的名称。 该列表按任意顺序排列 。它不包括特殊条目“。” 和“ ..”,即使它们存在

  • 问题内容: 我有一个自定义类对象(下面是示例)。 使用:我想将所有子列表“合并”到一个大列表中。因此,我认为我需要使自定义类成为可迭代的。 这是我的自定义类的示例。 我实现了,但是似乎没有用。他们甚至没有被召集。 知道我做错了什么吗? 注意:使用Python 3.3 问题答案: 当您尝试遍历类实例时调用的是什么: 是在返回的对象上调用的内容(在python2.x上,不是,我一般都对它们都使用别名,