如何使用pathlib测试目录操作?递归搜索JSON函数的单元测试方案
实现可模拟目录结构的FakePath用于pathlib函数单元测试
如果你需要为基于pathlib的递归搜索函数写单元测试,手动创建真实目录文件太麻烦?那这个FakePath实现绝对适合你——它能模拟Path对象的核心方法,让你轻松构建虚拟目录树,不用碰真实文件系统。
完整FakePath实现
from pathlib import Path from typing import List, Union class FakePath: def __init__(self, name: str = ""): self._name = name self._children: List[Union[FakePath, Path]] = [] @property def name(self): return self._name def add_children(self, *children: Union["FakePath", Path]): """添加子项,可以是FakePath(模拟目录)或真实Path(模拟文件)""" self._children.extend(children) def iterdir(self): """返回子项的迭代器,完全模拟Path.iterdir()的行为""" return iter(self._children) def resolve(self, strict: bool = False): """模拟Path.resolve(),虚拟路径无需解析,直接返回自身""" return self def is_dir(self): """判断是否为目录:FakePath默认是目录,真实Path按自身逻辑判断""" return True def is_file(self): """判断是否为文件,与is_dir()逻辑对应""" return not self.is_dir() # 可选:如果你的搜索函数用到suffix属性,可以补充这个方法 @property def suffix(self): # 针对FakePath模拟文件的场景,从name中提取后缀 if "." in self._name: return "." + self._name.split(".")[-1] return ""
核心方法说明
add_children:支持批量添加子项,既可以传FakePath(模拟子目录),也可以传真实Path对象(模拟文件),灵活适配测试场景iterdir():返回子项的迭代器,和真实Path.iterdir()的调用方式、返回格式完全一致resolve():因为是虚拟路径,直接返回自身即可满足函数调用需求is_dir()/is_file():模拟文件与目录的判断逻辑,确保你的递归搜索函数能正确区分遍历对象
你的示例场景实现
# 构建虚拟目录树 topdir = FakePath(name="top") subdir1 = FakePath(name="subdir1") # 添加模拟文件 subdir1.add_children(Path("file1"), Path("file2")) topdir.add_children(subdir1) # 遍历虚拟目录,输出子项名称 for dir_item in topdir.iterdir(): for file_item in dir_item.iterdir(): print(file_item.name)
运行后会输出:
file1 file2
单元测试示例(适配你的search函数)
假设你的search函数是递归查找所有.json文件,用pytest写测试的示例如下:
def test_search_json_files(): # 构建测试用虚拟目录 test_root = FakePath() subdir = FakePath() # 添加混合类型文件 subdir.add_children(Path("user.json"), Path("readme.txt"), Path("config.json")) test_root.add_children(subdir, Path("main.json")) # 调用你的搜索函数 found_files = search(test_root) # 提取文件名用于断言 found_names = [f.name for f in found_files] # 验证结果:所有.json文件都被找到 assert sorted(found_names) == sorted(["user.json", "config.json", "main.json"])
如果你的search函数用到了Path的其他方法,只需要在FakePath中补充对应的属性或方法即可,扩展性很强。
内容的提问来源于stack exchange,提问作者Alexey
相关产品推荐
相关产品推荐

