Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

python - 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. 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.

question from:https://stackoverflow.com/questions/65830675/is-it-possible-to-mock-os-scandir-and-its-attributes

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It depends on what you realy need to mock. The problem is that os.scandir returns entries of type os.DirEntry. One possibility is to use your own mock DirEntry and implement only the methods that you need (in your example, only path). For your example, you also have to mock 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. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...