Как проверить методы, которые вычисляют относительное время в Python, используя unitttest?

У меня есть метод в модели Django, который делает вычисления относительно текущего времени. Вот фрагмент:

def next_date():
    now = datetime.now()
    trial_expires = max(self.date_status_changed + timedelta(self.trial_days), now)
    return timezone.datetime(trial_expires.year, trial_expires.month+1, 1, tzinfo=trial_expires.tzinfo)

Как правильно проверить это в django / python с помощью unittest? Что я хотел бы сделать, так это уметь жестко кодировать некоторые значения для "сейчас" в тесте, чтобы я мог попробовать различные крайние случаи. В идеале я бы не хотел полагаться на текущее время и дату в тесте.

Один из подходов - изменить мой метод так, чтобы он принимал необязательный параметр, который переопределял бы значение "сейчас", которое он использует. Есть ли в Python какие-либо функции для выполнения чего-либо подобного без изменения сигнатуры моего метода?

1 ответ

Решение

Вы могли бы извлечь datetime.now() в качестве параметра:

def next_date(nowfunc=datetime.now):
    now = nowfunc()
    ...

или как зависимость класса:

class X:
    def __init__(self, nowfunc=datetime.now):
        self._nowfunc = nowfunc

def next_date(self):
    now = self._nowfunc()
    ...

И передайте имитирующую функцию с требуемым результатом ваших тестов.

Но если вы не хотите изменять подпись, используйте патчи:

@patch.object(datetime, 'now')
def test_next_date(self, nowfunc):
    nowfunc.return_value = ... # required result
    # the rest of the test
Другие вопросы по тегам