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

使用两个不同的文件在类中的Python模拟内置“打开”

鲜于岳
2023-03-14
问题内容

当他们都使用上下文管理器时,我很难弄清楚如何模拟类中的两个文件打开。我知道如何使用模拟模块对一个上下文管理的文件执行以下操作:

@patch('__builtin__.open')
def test_interface_mapping(self, mock_config):
        m = MagicMock(spec=file)
        handle = m.return_value.__enter__.return_value
        handle.__iter__.return_value = ('aa', 'bb')

我的问题是当一个类在同一调用中打开两个不同的文件时如何执行此操作。就我而言,该类__init__()将文件预加载到两个映射中。此类在其他类别中使用。我想模拟这两个文件的加载以提供我的测试数据,以便可以对我使用预加载的测试文件内容来测试使用IfAddrConfig对象的其他类。

这是我正在努力工作的类的示例,该类加载中的两个文件__init__(),我都想模拟这两个文件以加载测试注入的文件内容。getInterfaceMap()是经常调用的函数,因此我不希望每次调用时都加载并解析文件,因此是__init__()一次预加载地图的原因。

class IfAddrConfig(object):
    def __init__(self):
        # Initialize the static maps once since they require file operations
        # that we do not want to be calling every time getInterfaceMap() is used
        self.settings_map = self.loadSettings()
        self.config_map = self.loadConfig()

    def loadConfig(self):
        config_map = defaultdict(dict)
        with open(os.path.join('some_path.cfg'), 'r') as stream:
            for line in stream:
                # Parse line and build up config_map entries
        return config_map

    def loadSettings(self):
        settings_map = {}
        with open('another_path.cfg', 'r') as stream:
            for line in stream:
                # Parse line and build up settings_map entries
        return settings_map

    def getInterfaceMap(self, interface):
        # Uses both the settings and config maps to finally create a composite map
        # that is returned to called
        interface_map = {}
        for values in self.config_map.values():
            # Accesss self.settings_map and combine/compare entries with
            # self.config_map values to build new composite mappings that
            # depend on supplied interface value
        return interface_map

问题答案:

您必须使用side_effect修补open对象(mock_open)的属性,并且不要忘记设置return_valuefor__exit__方法。

@patch('__builtin__.open', spec=open)
def test_interface_mapping(self, mock_open):
    handle1 = MagicMock()
    handle1.__enter__.return_value.__iter__.return_value = ('aa', 'bb')
    handle1.__exit__.return_value=False
    handle2 = MagicMock()
    handle2.__enter__.return_value.__iter__.return_value = ('AA', 'BB')
    handle2.__exit__.return_value=False
    mock_open.side_effect = (handle1, handle2)
    with open("ppp") as f:
        self.assertListEqual(["aa","bb"],[x for x in f])
    with open("ppp") as f:
        self.assertListEqual(["AA","BB"],[x for x in f])

[编辑]当在contextlib中使用时,
我发现一种更为优雅的方法来[模拟内置的“打开”功能

所以你可以重写测试像

@patch('__builtin__.open', new_callable=mock_open, read_data="aa\nbb")
def test_interface_mapping_new(self, mo):
    handlers = (mo.return_value,mock_open(read_data="AA\nBB").return_value,)
    mo.side_effect = handlers
    with open("ppp") as f:
        self.assertEqual("aa\nbb",f.read())
    with open("ppp") as f:
        self.assertEqual("AA\nBB",f.read())

从python 3.4开始,您还可以使用readline(),readlines()而不模拟其他任何东西。



 类似资料:
  • 我试图打开两个实例ChromeDriver具有相同的配置文件如下: 问题是第一个驱动程序工作并导航到Google,但在第二个驱动程序中,我在实例化第二个驱动程序时遇到以下异常: 附加信息:抛出了一个带有空响应的异常,该异常向远程WebDriver服务器发送HTTP请求以获取URLhttp://localhost:6949/session.异常的状态为ReceiveFailure,消息为:基础连接已

  • 问题内容: 我试过了 但这会引发语法错误。我也尝试过像这样修补 有什么办法吗? 问题答案: 是python 2.x中的关键字,将其用作属性会引发SyntaxError。您可以通过在文件开头使用来避免这种情况。 注意:您不能简单地使用,因为除非禁用该语句,否则不会调用您修改的print函数。 编辑:您还需要在每个要使用修改后功能的文件中使用它,否则它将被该语句掩盖。

  • 我有两个文件命名为文章和类别。我使用SEO URL结构生成了一个URL格式。样品: 实例com/文章标题 实例com/类别标题 代码: 但有一个问题。我不能同时使用两种url格式。htaccess文件。他看到第一行,但忽略了另一行。但是我想对这两个文件使用相同的格式。你能帮忙吗?

  • 我正在使用Mockito编写单元测试,但我在模仿注入的类时遇到了问题。问题是两个注入的类是相同的类型,仅通过它们的注释来区分。如果我试图简单地模拟,那么在我的测试中,该模拟不会被注入,并且该对象为。我如何模拟这些对象?

  • 我们的Java应用程序在Logback上使用SLF4J来记录错误消息。在我们的回复中。xml,我们为错误日志定义了一个appender,以及一个指定包层次结构顶层的记录器。 我们正在将记录数据的功能添加到不同的日志文件中。我创建了一个类来处理这个日志记录,我向logback.xml添加了一个新的appender和一个新的logger。新的logger指定了我创建的新类的完全限定包名称(以及addt

  • 我有一个类,它有两个类似类型的字段。我嘲笑过他们两个。但是当我使用InjectMocks时,InjectMocks错误地将单个模拟注入到这两个字段中。 下面是示例代码类: 下面是我运行测试时的输出:testPrint()-intConsumer被注入到intConsumer和StringConsumer中。 我正在使用Maven。 我创建了这个私有构造函数,专门用于使用InjectMocks进行测