如何模仿zip fi

2021-01-18 21:48:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我想嘲笑一个ZipFile。尤其是,我需要一个模拟

  1. 通过了zipfile.is_zipfile()测试
  2. 返回zipfile.ZipFile().namelist()的字符串列表,并且
  3. 仅使用标准库。在

我正在测试的代码在给定的zip归档文件中查找潜在的Python模块1(即.py.zip,和.whl文件):

# utils.py

import zipfile
from pathlib import Path

def find_modules(archive=None):
    """Find modules within a given zip archive.

    Inputs:
        archive (str/Path): Zip archive

    Returns:
        list (str): List of module names as strings

    """

    possible_ext = ['.py'. '.zip', '.whl']
    modules = []

    if zipfile.is_zipfile(archive): 
        paths = [Path(p) for p in zipfile.ZipFile(archive).namelist()]
        modules = [p.stem for p in paths if p.stem != '__init__' and p.suffix in possible_ext]

    return modules

伏都教溶液

我拼凑了以下测试:

^{pr2}$

问题

我发现单靠@mock.path('zipfile.ZipFile')无法满足我的需求;它没有通过zipfile.is_zipfile()测试。在

  • 如果我正在模拟ZipFile对象,它是否应该自动通过zipfile.is_zipfile()测试?

  • 我发现我不能像使用is_zipfile那样使用相同的方法来重写is_zipfile。也就是说,需要一个额外的@mock.patch('zipfile.is_zipfile')。我的理解是,因为ZipFile定义了一个上下文,第一个return_value覆盖了上下文的__enter__,然后下一个命名空间是ZipFile方法级别。{{cd11>为什么这两种方法都有效?


# Test doesn't work
# Fails on: assert 0 == 3 
#            + where 0 = len([])
@mock.patch('zipfile.ZipFile')
def test_find_modules_return_value(self, mock_zipfile):
    mock_zipfile.return_value.is_zipfile.return_value = True
    mock_zipfile.return_value.namelist.return_value = self.MOCK_LISTING
    modules = utils.find_modules('dummy_archive.zip')

    assert len(modules) == 3
  • 也许我离基础太远了,有一种更简单的方法来模拟.zip存档?在

编辑

根据@Don Kirby的回答,我发现最直观的模式是:

def test_find_modules_return_value(self):
    # Create mock zipfile and override the is_zipfile function
    with mock.patch('mypackage.utils.zipfile') as mock_zipfile:
        mock_zipfile.is_zipfile.return_value = True
        mock_zipfile.namelist.return_value = self.MOCK_LISTING

        # Since a ZipFile is a separate object, which returns a zipfile (note 
        # that that's lowercase), we need to mock the ZipFile and have it return 
        # the zipfile mock previously created.
        with mock_patch('mypackage.utils.zipfile.ZipFile') as mock_ZipFile:
            mock_ZipFile.return_value = mock_zipfile

            modules = utils.find_modules("/dummy/path/to/check.zip")

    assert len(modules) == 3


1假设.zip文件可能包含模块,.zip和{}将在不同的进程中处理。在这一步中,我们只关心文件名。在