freezegun icon indicating copy to clipboard operation
freezegun copied to clipboard

Using freeze_time on a class prevents breaks class inheritance

Open IBestuzhev opened this issue 3 years ago • 3 comments

I want to inherit the test case and override the setup method and execute the same tests. Simplest code to reproduce the issue:

@freeze_time('2022-10-10', tick=True)
class TestOne(TestCase):
    @classmethod
    def setUpTestData(cls) -> None:
        print('do some preparations')
        return super().setUpTestData()

    def test_something(self):
        self.assertTrue(date.today().month == 10)


class TestTwo(TestOne):
    @classmethod
    def setUpTestData(cls) -> None:
        print('do another preparations')
        1 / 0
        return super().setUpTestData()

And I noticed that when I execute TestTwo the setUpTestData is not called at all. If I remove freeze_time it clearly fails with zero division error.

I think this happens due to the way setUpClass method is changed here, but I did not investigate it further.

The workaround I use is to use mixins and decorate final classes:

class TestMixin: ...

@freeze_time('2022-10-10', tick=True)
class TestOne(TestMixin, TestCase): pass

@freeze_time('2022-10-10', tick=True)
class TestTwo(TestMixin, TestCase): 
    @classmethod
    def setUpTestData(cls): ...

IBestuzhev avatar Sep 02 '22 10:09 IBestuzhev

Just checked a workaround from this issue - https://github.com/spulec/freezegun/issues/330

It also works.

IBestuzhev avatar Sep 02 '22 10:09 IBestuzhev

Using the decorator in a class doesn't really make semantic sense imo. The class is just a group, it's not a function.

boxed avatar Sep 02 '22 11:09 boxed

We have bumped into the same issue. After updating freezegun to v1.2.2 some of our test mixins stopped to work.

The tests look like below:

from unittest import TestCase

from freezegun import freeze_time


@freeze_time("2022-09-08 09:30:00")
class BaseTestClass(TestCase):
    pass


class MixIn(TestCase):

    def setUp(self):
        super().setUp()
        self.reached = True


class TestClass(BaseTestClass, MixIn):

    def test_if_reached(self):
        self.assertTrue(self.reached)

MixIn can be an AWS mock or other mocks with helpers.

The problem is that some tests, that were working fine before, started to fail after updating freezegun from 1.2.1 to 1.2.2.

Using the freezegun on the class is its basic feature that is included in the documentation. @boxed do mean that using decorator on the inherited base class in semantically incorrect or using the decorator for the class in general?

Or maybe you meant that in pytest style it is semantically incorrect. Do you think the same for tests written in UnitTest style? Please remember that pytest may be used just as a test runner.

sliwinski-milosz avatar Sep 08 '22 12:09 sliwinski-milosz