如何在 Python 中模拟 os.listdir 来假装文件和目录?

How to mock os.listdir to pretend files and directories in Python?(如何在 Python 中模拟 os.listdir 来假装文件和目录?)
本文介绍了如何在 Python 中模拟 os.listdir 来假装文件和目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个专有的存储库格式,我正在尝试开发一个 Python 模块来处理这些存储库.回购格式如下:

I have a proprietary repository format and I'm trying to develop a Python module to process these repositories. Repo format goes as:

/home/X/
       |
       + alpha/
       |
       + beta/
       |
       + project.conf

这里,X 是一个项目.alphabeta 是本项目中的文件夹,它们代表本项目中的.group 是这个 repo 中的一个容器,它所代表的内容实际上与这个问题无关.repo X 在其根级别也有文件;project.conf 就是此类文件的一个示例.

Here, X is a project. alpha and beta are folders inside this project and they represent groups in this project. A group is a container in this repo and what it represents is really not relevant for this question. The repo X also has files in its root level; project.conf is an example of such a file.

我有一个名为Project 的类,它抽象出X 等项目.Project 类有一个 load() 方法,用于构建内存中的表示.

I have a class called Project that abstracts projects such as X. The Project class has a method load() that builds an in-memory representation.

class Project(object):

    def load(self):
        for entry in os.listdir(self.root):
            path = os.path.join(self.root, entry)
            if os.path.isdir(path):
                group = Group(path)
                self.groups.append(group)
                group.load()
            else:
                # process files ...

要通过模拟文件系统对 load() 方法进行单元测试,我有:

To unit test the load() method by mocking the file system, I have:

import unittest
from unittest import mock
import Project

class TestRepo(unittest.TestCase):

    def test_load_project(self):
        project = Project("X")

        with mock.patch('os.listdir') as mocked_listdir:
            mocked_listdir.return_value = ['alpha', 'beta', 'project.conf']
            project.load()
            self.assertEqual(len(project.groups), 2)

这确实模拟了 os.listdir 成功.但我无法欺骗 Python 将 mocked_listdir.return_value 视为由文件和目录组成.

This does mock os.listdir successfully. But I can't trick Python to treat mocked_listdir.return_value as consisting of files and directories.

我如何模拟 os.listdiros.path.isdir在同一个测试中,这样测试就会看到alphabeta 作为目录,project.conf 作为文件?

How do I mock either os.listdir or os.path.isdir, in the same test, such that the test will see alpha and beta as directories and project.conf as a file?

推荐答案

我设法通过将一个可迭代对象传递给模拟的 isdirside_effect 属性来实现所需的行为对象.

I managed to achieve the desired behavior by passing an iterable to the side_effect attribute of the mocked isdir object.

import unittest
from unittest import mock
import Project

class TestRepo(unittest.TestCase):

  def test_load_project(self):
      project = Project("X")

      with mock.patch('os.listdir') as mocked_listdir:
        with mock.patch('os.path.isdir') as mocked_isdir:
          mocked_listdir.return_value = ['alpha', 'beta', 'project.conf']
          mocked_isdir.side_effect = [True, True, False]
          project.load()
          self.assertEqual(len(project.groups), 2)

关键是 mocked_isdir.side_effect = [True, True, False] 行.可迭代对象中的布尔值应与传递给 mocked_listdir.return_value 属性的目录和文件条目的顺序相匹配.

The key is the mocked_isdir.side_effect = [True, True, False] line. The boolean values in the iterable should match the order of directory and file entries passed to the mocked_listdir.return_value attribute.

这篇关于如何在 Python 中模拟 os.listdir 来假装文件和目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

patching a class yields quot;AttributeError: Mock object has no attributequot; when accessing instance attributes(修补类会产生“AttributeError:Mock object has no attribute;访问实例属性时)
How to mock lt;ModelClassgt;.query.filter_by() in Flask-SqlAlchemy(如何在 Flask-SqlAlchemy 中模拟 lt;ModelClassgt;.query.filter_by())
FTPLIB error socket.gaierror: [Errno 8] nodename nor servname provided, or not known(FTPLIB 错误 socket.gaierror: [Errno 8] nodename nor servname provided, or not known)
Weird numpy.sum behavior when adding zeros(添加零时奇怪的 numpy.sum 行为)
Why does the #39;int#39; object is not callable error occur when using the sum() function?(为什么在使用 sum() 函数时会出现 int object is not callable 错误?)
How to sum in pandas by unique index in several columns?(如何通过几列中的唯一索引对 pandas 求和?)