简体   繁体   English

是否可以模拟 os.scandir 及其属性?

[英]Is it possible to mock os.scandir and its attributes?

for entry in os.scandir(document_dir)
    if os.path.isdir(entry):
    # some code goes here
    else:
        # else the file needs to be in a folder
        file_path = entry.path.replace(os.sep, '/')

I am having trouble mocking os.scandir and the path attribute within the else statement.我遇到问题 mocking os.scandir 和 else 语句中的路径属性。 I am not able to mock the mock object's property I created in my unit tests.我无法模拟我在单元测试中创建的模拟对象的属性。

with patch("os.scandir") as mock_scandir:
    # mock_scandir.return_value = ["docs.json", ]
    # mock_scandir.side_effect = ["docs.json", ]
    # mock_scandir.return_value.path = PropertyMock(return_value="docs.json")

These are all the options I've tried.这些都是我尝试过的所有选项。 Any help is greatly appreciated.任何帮助是极大的赞赏。

It depends on what you realy need to mock.这取决于你真正需要模拟什么。 The problem is that os.scandir returns entries of type os.DirEntry .问题是os.scandir返回os.DirEntry类型的条目。 One possibility is to use your own mock DirEntry and implement only the methods that you need (in your example, only path ).一种可能性是使用您自己的模拟DirEntry并仅实现您需要的方法(在您的示例中,只有path )。 For your example, you also have to mock os.path.isdir .对于您的示例,您还必须模拟os.path.isdir Here is a self-contained example for how you can do this:这是一个独立的示例,说明如何执行此操作:

import os
from unittest.mock import patch


def get_paths(document_dir):
    # example function containing your code
    paths = []
    for entry in os.scandir(document_dir):
        if os.path.isdir(entry):
            pass
        else:
            # else the file needs to be in a folder
            file_path = entry.path.replace(os.sep, '/')
            paths.append(file_path)
    return paths


class DirEntry:
    def __init__(self, path):
        self.path = path

    def path(self):
        return self.path


@patch("os.scandir")
@patch("os.path.isdir")
def test_sut(mock_isdir, mock_scandir):
    mock_isdir.return_value = False
    mock_scandir.return_value = [DirEntry("docs.json")]
    assert get_paths("anydir") == ["docs.json"]

Depending on your actual code, you may have to do more.根据您的实际代码,您可能需要做更多的事情。

If you want to patch more file system functions, you may consider to use pyfakefs instead, which patches the whole file system.如果你想修补更多的文件系统功能,你可以考虑使用pyfakefs来代替,它会修补整个文件系统。 This will be overkill for a single test, but can be handy for a test suite relying on file system functions.这对于单个测试来说是多余的,但对于依赖文件系统功能的测试套件来说可能很方便。

Disclaimer: I'm a contributor to pyfakefs.免责声明:我是 pyfakefs 的贡献者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM