为什么在使用 Pyfakefs 时 Path.rename 上出现 FileNotFoundError?
Why FileNotFoundError on Path.rename while using Pyfakefs?
我为重命名文件的函数编写了一个测试,例如/videos/vid_youtube.mp4
到 /videos/youtube/vid.mp4
。测试使用 Pyfakefs 修补 fs。
当代码实际重命名文件时,出现此错误。
FileNotFoundError: [Errno 2] No such file or directory: '/home/user/code/project/test/DLV/videos/vid_youtube.mp4' -> '/home/user/code/project/test/DLV/videos/youtube/vid.mp4'
这就是我设置 fakefs 的方式
def setUp(self) -> None:
self.setUpPyfakefs()
self.fs.create_dir(Path(Dirs.VIDEOS)) # /home/user/code/project/test/DLV/videos
self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))
正在测试的代码。
class Files:
@staticmethod
def rename_video_files():
all_files = Collect.video_files()
for files_for_type in all_files:
for file in all_files[files_for_type]:
path = Path(file)
platform = Files.detect_platform(path)
platform_dir = Path(Dirs.VIDEOS, platform)
platform_dir.mkdir(exist_ok=True)
new_name = path.stem.replace(f'_{platform}', '')
new_path = Dirs.VIDEOS / platform / f'{new_name}{path.suffix}'
old_path = Dirs.VIDEOS / path
old_path.rename(new_path) # throws FileNotFoundError
我调试了测试和被测方法,甚至将假 fs 传递给 rename_video_files(fakefs) 以检查文件和目录。所有文件和目录看起来都是正确的。
这里出了什么问题?
这里的问题很可能是 Dirs.VIDEOS
的静态初始化。这在加载时初始化为 pathlib.Path
,并且不会在您稍后设置 pyfakefs
时进行修补(如果您在哪里使用 unittest.patch
进行修补,也会发生同样的问题) .
有两种方法可以解决这个问题:
- 调整代码以不静态初始化路径
这可以通过静态定义 str
路径,并在 运行 时将其转换为 Path
来完成,或者使用一种方法来获取路径而不是属性(例如 Dirs.VIDEO()
而不是 Dirs.VIDEO`).
- 调整测试以重新加载测试代码
如果在 pyfakefs
初始化后重新加载测试代码,它将正确修补。 pyfakefs
在 setUpPyfakefs
中提供了一个 argument 来做到这一点:
from pyfakefs.fake_filesystem_unittest import TestCase
from my_module import video_files
from my_module.video_files import Dirs, Files
class MyTest(TestCase):
def setUp(self) -> None:
self.setUpPyfakefs(modules_to_reload=[video_files])
self.fs.create_dir(
Path(Dirs.VIDEOS)) # /home/user/code/project/test/DLV/videos
self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))
(假设您的测试代码位于 my_module.video_files.py
)
免责声明:
我是 pyfakefs 的贡献者。
我为重命名文件的函数编写了一个测试,例如/videos/vid_youtube.mp4
到 /videos/youtube/vid.mp4
。测试使用 Pyfakefs 修补 fs。
当代码实际重命名文件时,出现此错误。
FileNotFoundError: [Errno 2] No such file or directory: '/home/user/code/project/test/DLV/videos/vid_youtube.mp4' -> '/home/user/code/project/test/DLV/videos/youtube/vid.mp4'
这就是我设置 fakefs 的方式
def setUp(self) -> None:
self.setUpPyfakefs()
self.fs.create_dir(Path(Dirs.VIDEOS)) # /home/user/code/project/test/DLV/videos
self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))
正在测试的代码。
class Files:
@staticmethod
def rename_video_files():
all_files = Collect.video_files()
for files_for_type in all_files:
for file in all_files[files_for_type]:
path = Path(file)
platform = Files.detect_platform(path)
platform_dir = Path(Dirs.VIDEOS, platform)
platform_dir.mkdir(exist_ok=True)
new_name = path.stem.replace(f'_{platform}', '')
new_path = Dirs.VIDEOS / platform / f'{new_name}{path.suffix}'
old_path = Dirs.VIDEOS / path
old_path.rename(new_path) # throws FileNotFoundError
我调试了测试和被测方法,甚至将假 fs 传递给 rename_video_files(fakefs) 以检查文件和目录。所有文件和目录看起来都是正确的。
这里出了什么问题?
这里的问题很可能是 Dirs.VIDEOS
的静态初始化。这在加载时初始化为 pathlib.Path
,并且不会在您稍后设置 pyfakefs
时进行修补(如果您在哪里使用 unittest.patch
进行修补,也会发生同样的问题) .
有两种方法可以解决这个问题:
- 调整代码以不静态初始化路径
这可以通过静态定义str
路径,并在 运行 时将其转换为Path
来完成,或者使用一种方法来获取路径而不是属性(例如Dirs.VIDEO()
而不是 Dirs.VIDEO`). - 调整测试以重新加载测试代码
如果在pyfakefs
初始化后重新加载测试代码,它将正确修补。pyfakefs
在setUpPyfakefs
中提供了一个 argument 来做到这一点:
from pyfakefs.fake_filesystem_unittest import TestCase
from my_module import video_files
from my_module.video_files import Dirs, Files
class MyTest(TestCase):
def setUp(self) -> None:
self.setUpPyfakefs(modules_to_reload=[video_files])
self.fs.create_dir(
Path(Dirs.VIDEOS)) # /home/user/code/project/test/DLV/videos
self.fs.create_file(Path(Dirs.VIDEOS / "vid_youtube.mp4"))
(假设您的测试代码位于 my_module.video_files.py
)
免责声明:
我是 pyfakefs 的贡献者。