I wrote a test for a function that renames files from e.g. /videos/vid_youtube.mp4
to /videos/youtube/vid.mp4
. The test patches the fs with Pyfakefs.
When the code actually renames the file, I get this error.
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'
This is how I set up 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"))
The code under test.
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
I debugged the test and the method under test and even passed the fake fs to rename_video_files(fakefs) to inspect the files and directories. All files and directories look correct.
What is going wrong here?
The problem here is most likely the static initialization of
Dirs.VIDEOS
. This is initialized at load time as apathlib.Path
, and won't be patched later at the time you setuppyfakefs
(the same problem would happen if you where to useunittest.patch
for patching).There are two ways to fix this:
This could be done by statically defining the
str
path, and converting it to aPath
at run time, or by using a method to get the path instead of an attribute (e.g.Dirs.VIDEO()
instead of Dirs.VIDEO`).If reloading the tested code after
pyfakefs
has been initialized, it will be correctly patched.pyfakefs
provides an argument insetUpPyfakefs
that does that:(under the assumption, that your code under test is located in
my_module.video_files.py
)Disclaimer:
I'm a contributor to pyfakefs.