Monkey-patching time.time
, вероятно, вполне достаточно, поскольку он обеспечивает основу для почти всех других основанных на времени подпрограмм в Python. Похоже, что он достаточно хорошо справляется с вашим вариантом использования, не прибегая к более сложным трюкам, и не имеет значения, когда вы это делаете (кроме нескольких пакетов stdlib, таких как Queue.py и threading.py, которые в этом случае from time import time
) вы должны исправить, прежде чем они будут импортированы):
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2010, 4, 17, 14, 5, 35, 642000)
>>> import time
>>> def mytime(): return 120000000.0
...
>>> time.time = mytime
>>> datetime.datetime.now()
datetime.datetime(1973, 10, 20, 17, 20)
Тем не менее, в годы моделирования объектов для различных типов автоматизированного тестирования, я нуждался в таком подходе очень редко, так как большую часть времени мне нужен код моего собственного приложения, а не процедуры stdlib. В конце концов, вы знаете, они уже работают. Если вы сталкиваетесь с ситуациями, когда ваш собственный код должен обрабатывать значения, возвращаемые библиотечными подпрограммами, возможно, вы захотите смоделировать сами библиотечные подпрограммы, по крайней мере при проверке того, как ваше собственное приложение будет обрабатывать временные метки.
Наилучшим подходом на сегодняшний день является создание собственной подпрограммы (служб) для даты / времени, которые вы используете исключительно в коде своего приложения, и встраивание в нее способности тестов выдавать ложные результаты по мере необходимости. Например, я иногда делаю более сложный эквивалент этого:
# in file apptime.py (for example)
import time as _time
class MyTimeService(object):
def __init__(self, get_time=None):
self.get_time = get_time or _time.time
def __call__(self):
return self.get_time()
time = MyTimeService()
Теперь в моем коде приложения я просто делаю import apptime as time; time.time()
, чтобы получить текущее значение времени, тогда как в тестовом коде я сначала могу сделать apptime.time = MyTimeService(mock_time_func)
в своем коде setUp()
, чтобы получить поддельные результаты времени.
Обновление: Спустя годы есть альтернатива, как отмечено в Ответ Дейва Форгака .