1

我目前正在为我的应用程序编写单元测试,并且我有一个常见错误,即在会话已经关闭后函数想要访问数据库对象。为了确保应用程序中不存在此错误,我想故意触发它。如果我有它,我会修复错误并确保它永远消失。

但是,我似乎很难做到这一点:

DBSession = scoped_session(
                sessionmaker(
                    extension=ZopeTransactionExtension(),
                    ))
db_session = DBSession()
obj = Object()
db_session.add(obj)
obj.property = "a"
db_session.expire_on_commit = True
db_session.expire(obj)
db_session.expunge(obj)
transaction.commit()
db_session.close()
assert obj.property == "a"

这是正在发生的事情的一个简短示例。我希望触发异常transaction.commitdb_session.close()但即使是上面的组合代码(从谷歌搜索来看,这似乎是组合错误的所有来源)都不能触发这个异常。

真正的错误来自于此:我有一个数据库存储会话,一旦我想在 cookie 中设置会话 ID,会话就会说它已分离。所以我只会在本地缓存它,它不会像我一样在它创建后改变。

最后,当尝试像这样故意使其过期时:

assert obj in db_session
db_session.expire(obj)

我得到一个例外:InvalidRequestError: Instance ... is not persistent within this Session. 这让我完全困惑......在这里谷歌搜索并没有发现任何有用的信息。有任何想法吗?

编辑:感谢 zzzeek 的评论,我还测试了:

assert db_session is \
        orm.session.Session.object_session(obj)
assert isinstance(obj, Object)
assert isinstance(Object.property, orm.attributes.InstrumentedAttribute)

注意:所有代码示例都被缩短和转换,但这些操作是以这种方式执行的,并且所有assert语句都成立。

编辑 2:我必须在上面的代码中修复一个错误并替换

obj = db_session.query(Object)[0] # Object is from DB, just a short example

经过

obj = Object()
db_session.add(obj)

因为它实际上是新创建对象而不是查询它。查询作品找到(对不起!)

编辑3:不知何故,我解决了原来的问题:我现在可以强制我最初想要的异常。但是,我仍然无法解释InvalidRequestError,所以我决定做一个基本的要点来证明这个问题:https ://gist.github.com/Javex/5885669 。您可以将其作为独立脚本运行,也可以通过py.test.

4

0 回答 0