Python单元测试Mock ZipFile时测试无法通过的问题咨询
问题排查与修正方案
- 函数调用错误:测试代码中调用的是
get_ast_nodes,但待测试的业务函数名为get_files,函数名不匹配无法触发目标逻辑。 - 模拟属性错误:
archive.filelist是ZipFile实例的普通属性,不是可调用方法,不需要加.return_value赋值,直接给mock_zipfile.return_value.filelist赋值列表即可。 - Mock路径错误:
@mock.patch('zipfile.ZipFile')的写法不符合Mock的「在哪里使用就在哪里Patch」原则,需要将Patch路径替换为业务代码所在模块中导入的ZipFile路径,例如业务代码存放在utils.py中则改为@mock.patch('utils.zipfile.ZipFile'),否则Mock无法替换业务代码中实际调用的ZipFile对象。 - 路径拼接隐患(非测试失败直接原因,可优化):业务代码中
os.path.join直接接收Path类型的zip_path参数,建议先转为字符串再拼接,避免跨系统兼容性问题。
修正后测试代码
# 假设业务代码在your_module模块下,替换为你实际的模块名 @mock.patch('your_module.zipfile.ZipFile') def test_get_files(mock_zipfile): mock_zipfile.return_value.filelist = [ zipfile.ZipInfo('py_file.py'), zipfile.ZipInfo('py_file.py'), zipfile.ZipInfo('any_file.any') ] python_files = get_files(Path('/dummy/path/archive.zip')) assert len(python_files) == 2
业务代码优化建议
原业务代码未主动关闭ZipFile实例,存在资源泄漏风险,可改为上下文管理器写法:
def get_files(zip_path: Path): zip_full_path = os.path.join(os.path.dirname(__file__), '..', str(zip_path)) with zipfile.ZipFile(zip_full_path) as archive: return [x for x in archive.filelist if x.filename.endswith(".py")]
内容的提问来源于stack exchange,提问作者Franz
相关产品推荐
相关产品推荐

