[SOLVED] Freezetime does not work with FastAPI test client

Issue

This Content is from Stack Overflow. Question asked by dan

Freezetime does not seem to work with FastAPI TestClient.
I have build this simple example, the test is failing.
Freezetime does not override datetime in this case :/

import datetime

from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
from freezegun import freeze_time

app = FastAPI()


class Message(BaseModel):
    message: str = "Hello World"
    timestamp: datetime.datetime = datetime.datetime.utcnow()


@app.get("/", response_model=Message)
def main() -> Message:
    return Message()


client = TestClient(app)

@freeze_time('2022-09-18T13:36:41.624237')
def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {
            'message': 'Hello World',
            'timestamp': '2022-09-18T13:36:41.624237'
            }

when I run pytest I am getting this message

    @freeze_time('2022-09-18T13:36:41.624237')
    def test_read_main():
        response = client.get("/")
        assert response.status_code == 200
>       assert response.json() == {
                'message': 'Hello World',
                'timestamp': '2022-09-18T13:36:41.624237'
                }
E       AssertionError: assert {'message': '...44:25.021208'} == {'message': '...36:41.624237'}
E         Omitting 1 identical items, use -vv to show
E         Differing items:
E         {'timestamp': '2022-09-18T13:44:25.021208'} != {'timestamp': '2022-09-18T13:36:41.624237'}
E         Use -v to get more diff

Any ideas if these kind of tests are possible with the FastAPI TestClient ?



Solution

As mentioned here, define another function and assign the reference of that function to the model. That way, the freezegun should be able to override the datetime.

...
from pydantic import Field

def current_time():
    return datetime.datetime.utcnow()

class Message(BaseModel):
    message: str = "Hello World"
    timestamp: datetime.datetime = Field(default_factory=current_time)
...


This Question was asked in StackOverflow by dan and Answered by Myrat It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?