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?
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.