Python 如何在sqlalchemy中模拟创建的时间?
我在烧瓶应用程序中使用SQLAlchemy。在我的测试中,我尝试为我的条目模拟自动创建和更新时间。但我不明白它对炼金术是如何起作用的。例如,我尝试模拟datetime创建,但失败了。例如:Python 如何在sqlalchemy中模拟创建的时间?,python,unit-testing,testing,sqlalchemy,mocking,Python,Unit Testing,Testing,Sqlalchemy,Mocking,我在烧瓶应用程序中使用SQLAlchemy。在我的测试中,我尝试为我的条目模拟自动创建和更新时间。但我不明白它对炼金术是如何起作用的。例如,我尝试模拟datetime创建,但失败了。例如: class Entry(db.Model): __tablename__ = 'entries' created = db.Column(db.DateTime(), default=db.func.now()) updated = db.Column(db.DateTime(), d
class Entry(db.Model):
__tablename__ = 'entries'
created = db.Column(db.DateTime(), default=db.func.now())
updated = db.Column(db.DateTime(), default=db.func.now(), onupdate=db.func.now())
class ViewTestCase(AppliactionTestCase):
def test(self):
with freeze_time("2014-06-01 16:00:00"):
db.session.add(Entry())
db.session.commit()
entry = db.session.query(Entry).first()
self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))
还有一个问题。如果我需要为条目刷新
更新的
,如何在没有更改的情况下强制保存条目?仅冻结修补程序datetime.datetime.now
。您可以通过以下两种方式之一解决此问题:
mock.patch
来修补db.func.now()
default=datetime.datetime.now
,这样冷冻枪就能正确地修补它sqlalchemy提供钩子
sqlalchemy.event
api来修补查询会话
先决条件:炼金术、pytest、冻结、上下文库
以@prokoptesev使用的flask sqlalchemy为例:
class Entry(db.Model):
__tablename__ = 'entries'
created = db.Column(db.DateTime(), default=db.func.now())
updated = db.Column(db.DateTime(), default=db.func.now(), onupdate=db.func.now())
只需编写pytest fixtures来修补行创建时间:
import datetime
from flask_sqlalchemy import event
from contextlib import contextmanager
from freezegun import freeze_time
import Entry
# if you want the code be commonly used, change Entry to db.Model instead
@contextmanager
def patch_time(time_to_freeze, tick=True):
with freeze_time(time_to_freeze, tick=tick) as frozen_time:
def set_timestamp(mapper, connection, target):
now = datetime.datetime.now()
if hasattr(target, 'created'):
target.created = now
if hasattr(target, 'updated'):
target.updated = now
event.listen(Entry, 'before_insert', set_timestamp,
propagate=True)
yield frozen_time
event.remove(Entry, 'before_insert', set_timestamp)
@pytest.fixture(scope='function')
def patch_current_time():
return patch_time
然后编写pytest类型测试用例:
def test_patch_insert_time(patch_current_time, assertions):
with patch_current_time("2014-06-01 16:00:00", tick=False):
db.session.add(Entry())
db.session.commit()
entry = db.session.query(Entry).first()
assert entry.created == datetime(2014, 6, 1, 16, 0, 0)
如果有人使用unittools
或其他测试包,您也可以直接使用patch\u time函数:
class ViewTestCase(AppliactionTestCase):
def test(self):
with patch_time("2014-06-01 16:00:00", tick=False):
db.session.add(Entry())
db.session.commit()
entry = db.session.query(Entry).first()
self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))
快乐的编码。这对我不起作用。我不知道它在引擎盖下是如何工作的,但如果我在模型中使用
default=datetime.datetime.now
,datetime已修补,但在已保存的模型中created
返回当前时间。我如何修补db.func.now
?如果我错了,请纠正我db.func.now
是保存模型时的数据库功能。可能是修补错误?相对于您的测试,条目
类在哪里?抱歉,我不明白您的意思。