pythonpyfakefs

Fake pathlib.Path in class variable using pyfakefs'


I have a class variable of type pathlib.Path.

from pathlib import Path


class MyClass:
    FILE_PATH = Path('/etc/ids.json')

I know that pyfakefs is not able to mock this automatically. So in my test I use its Patcher class (I also tried other ways.) to reload the corresponding module.

from pathlib import Path
from pyfakefs.fake_filesystem_unittest import Patcher
from pyfakefs.fake_pathlib import FakePathlibModule

from . import my_class


def test_class_variable(fs):
    # my_class.MyClass.FILE_PATH = Path('/etc/ids.json')
    with Patcher(modules_to_reload=[my_class]):
        assert type(my_class.MyClass.FILE_PATH) is FakePathlibModule.PosixPath

But it still isn't mocked.

If I uncomment the commented line, the test succeeds.

What should I do to mock the class variable?


Solution

  • The problem here is that you create the patcher twice: once via the fs fixture, and once manually via the Patcher instantiation.

    pyfakefs does not support nested filesystem mocks - in case of nesting it just uses the existing one. This is somewhat described in the caution about module- and session-scoped fixtures, but probably needs a more prominent place in the documentation, as this is true independent of the usage of module or session-scoped fixtures.

    The easiest way to fix this is to just omit the fs fixture here:

    def test_class_variable():
        with Patcher(modules_to_reload=[my_class]):
            assert type(my_class.MyClass.FILE_PATH) is FakePathlibModule.PosixPath
    

    If you need this more than once (or if you don't want that setup in the test itself), you can instead create your own fixture:

    @pytest.fixture
    def my_fs():
        with Patcher(modules_to_reload=[my_class]) as p:
            yield p.fs
    
    
    def test_class_variable(my_fs):
        assert type(my_class.MyClass.FILE_PATH) is FakePathlibModule.PosixPath
    

    Disclaimer:
    I'm a maintainer of pyfakefs.

    Update:
    A added a chapter about nested fake filesystems to the troubleshouting guide.