Fake utcnow for the pytest I want to create a pytest with a fake utcnow, but also I need to preserve the functionality of all other datetime methods. Simple example here:

import datetime as dt


class FakeTime(dt.datetime):
    fake_time = None

    @classmethod
    def utcnow(cls):
        return cls.fake_time


def str_2_time(str_dt: str) -&gt; dt.datetime:
    """Shortcut to do convert the string to datetime"""
    return dt.datetime.strptime(str_dt, '%Y-%m-%d %H:%M')


def test_patch_datetime():
    for utc_time in ['2019-01-01 10:00', '2019-02-01 13:00', '2019-03-01 16:00']:
        FakeTime.fake_time = str_2_time(utc_time)
        dt.datetime = FakeTime
        assert dt.datetime.utcnow() == str_2_time(utc_time)


Is this the right way?

The method str_2_time just need to show that all other methods of the datetime works fine.
According to this, subclassing datetime.datetime seems the way to go.

There is no use for the str_2_time method though. You can easily inline this, or even simpler, just use the datetime.datetime constructor:

def test_patch_datetime():
    for utc_time in [
        dt.datetime(2019, 1, 1, 10),
        dt.datetime(2019, 2, 1, 13),
        dt.datetime(2019, 3, 1, 16),
    ]:
        FakeTime.fake_time = utc_time
        dt.datetime = FakeTime
        assert dt.datetime.utcnow() == utc_time


You should be aware that this can have side effects in other parts of your code, so it might be needed to replace it back with the original class after  the test method:

def test_patch_datetime():
    datetime_orig = dt.datetime

    utc_times = [
        dt.datetime(2019, 1, 1, 10),
        dt.datetime(2019, 2, 1, 13),
        dt.datetime(2019, 3, 1, 16),
    ]
    for utc_time in utc_times:
        FakeTime.fake_time = utc_time
        dt.datetime = FakeTime
        assert dt.datetime.utcnow() == utc_time
    dt.datetime = datetime_orig
    # print(dt.datetime.utcnow())
    assert dt.datetime.utcnow() &gt; max(utc_times)