一个捕捉修改数据库的方式,是用这样的使用SQLAlchemy的会话扩展机制和拦截刷新到数据库:
from sqlalchemy.orm.attributes import instance_state
from sqlalchemy.orm import SessionExtension
class MockExtension(SessionExtension):
def __init__(self):
self.clear()
def clear(self):
self.updates = set()
self.inserts = set()
self.deletes = set()
def before_flush(self, session, flush_context, instances):
for obj in session.dirty:
self.updates.add(obj)
state = instance_state(obj)
state.commit_all({})
session.identity_map._mutable_attrs.discard(state)
session.identity_map._modified.discard(state)
for obj in session.deleted:
self.deletes.add(obj)
session.expunge(obj)
self.inserts.update(session.new)
session._new = {}
然后做检查,你可以与模拟配置会话看看它是否符合你的期望。
mock = MockExtension()
Session = sessionmaker(extension=[mock], expire_on_commit=False)
def do_something(attr):
session = Session()
obj = session.query(Cls).first()
obj.attr = attr
session.commit()
def test_something():
mock.clear()
do_something('foobar')
assert len(mock.updates) == 1
updated_obj = mock.updates.pop()
assert updated_obj.attr == 'foobar'
但是你要至少做一些测试与数据库反正因为你ATLEAST想知道如果你的查询正常工作。并且请记住,您还可以通过session.update()
,.delete()
和.execute()
修改数据库。
嗨,因为我的一些同事坚持我们应该使用存储过程,并且我没有控制权,所以sqlite对我来说不是一种可能的选择。 – ablmf 2009-08-25 07:33:16
顺便说一句:sqlite不支持存储过程。 – ablmf 2009-08-25 08:38:02
嗯。这意味着你将不得不模拟代码的重要部分(存储过程)。这将使测试更加有用。棘手的情况。 – 2009-08-25 10:55:04