一個捕捉修改數據庫的方式,是用這樣的使用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