Skip to content

Commit f4bf942

Browse files
committed
Support fixtures inside classes decorated with freeze_time
1 parent ba06fa4 commit f4bf942

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

freezegun/api.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,6 @@ def tearDown(*args: Any, **kwargs: Any) -> None:
693693
klass.tearDown = tearDown # type: ignore[method-assign]
694694

695695
else:
696-
697696
seen = set()
698697

699698
klasses = klass.mro()
@@ -707,7 +706,20 @@ def tearDown(*args: Any, **kwargs: Any) -> None:
707706
continue
708707

709708
try:
710-
setattr(klass, attr, self(attr_value))
709+
if attr_value.__dict__.get("_pytestfixturefunction") and hasattr(attr_value, "__pytest_wrapped__"):
710+
# PYTEST==8.2.x (and maybe others)
711+
# attr_value is a pytest fixture
712+
# In other words: attr_value == fixture(original_method)
713+
# We need to keep the fixture itself intact to ensure pytest still treats it as a fixture
714+
# We still want to freeze time inside the original_method though
715+
attr_value.__pytest_wrapped__.obj = self(attr_value.__pytest_wrapped__.obj)
716+
elif attr_value.__dict__.get("_fixture_function"):
717+
# PYTEST==8.4.x
718+
# Same
719+
attr_value._fixture_function = self(attr_value._fixture_function)
720+
else:
721+
# Wrap the entire method inside 'freeze_time'
722+
setattr(klass, attr, self(attr_value))
711723
except (AttributeError, TypeError):
712724
# Sometimes we can't set this for built-in types and custom callables
713725
continue

tests/test_class_decorator.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from datetime import datetime
2+
from unittest import TestCase
3+
4+
import pytest
5+
from freezegun import freeze_time
6+
from freezegun.api import FakeDatetime
7+
8+
@freeze_time("2022-10-01")
9+
class TestClassDecoratorWithFixture:
10+
@pytest.fixture
11+
def ff(self) -> datetime:
12+
return datetime.now()
13+
14+
def test_with_fixture(self, ff: datetime) -> None:
15+
assert ff == FakeDatetime(2022, 10, 1, 0, 0)
16+
assert datetime.now() == FakeDatetime(2022, 10, 1, 0, 0)
17+
18+
def test_without_fixture(self) -> None:
19+
assert datetime.now() == FakeDatetime(2022, 10, 1, 0, 0)

0 commit comments

Comments
 (0)