spulec / freezegun

Let your Python tests travel through time
Apache License 2.0
4.2k stars 269 forks source link

Freezegun doesn't work with django.db.models.functions.now() #378

Open rollue opened 3 years ago

rollue commented 3 years ago

We are working on a Gathering model that checks the date(=appointment) to be in the future. @chancellor-dev

from django.db.models.functions import Now

class Gathering(UUIDModel, TimeStampedModel):
    ...

    # https://stackoverflow.com/questions/49882526/validation-for-datefield-so-it-doesnt-take-future-dates-in-django
    class Meta:
        constraints = [
            models.CheckConstraint(
                check=models.Q(date__gte=Now()), name="date_cannot_be_past_dated"
            )
        ]

When I run pytest, I get: django.db.utils.IntegrityError: new row for relation "gatherings_gathering" violates check constraint "date_cannot_be_past_dated"

@freeze_time("2021-01-07")
def test_gathering_create_serializer(fake_request):
    data = {
        ...
        "date": dt.date(2021, 1, 12),
    }

    # load data to serializer
    ser = GatheringWriteSerializer(data=data, context={"request": fake_request})
    assert ser.is_valid(raise_exception=True)

    gathering = ser.save()  # <-- error raised her

It looks like freezegun doesn't freeze the low-level database function - my thoughts are that freezegun only freezes the code at the python application level, not at the database(postgresql in my case) level.

My current workaround is using from django.utils.timezone import now instead of django.db.models.functions.now() in the CheckConstraint expression, but I wonder if it's legit? Any suggestions?

C0DK commented 3 years ago

I am wondering about the same, and am pretty much at a halt. Not sure how to test my functions, sadly.