在ActiveRecord单元测试中处理查询缓存是否重要?

时间:2010-02-23 03:03:09

标签: ruby-on-rails unit-testing activerecord query-cache

在Hibernate世界中,您通常可以进行单元测试,但实际上存在因为您正在处理缓存数据而未显示的错误。例如,您可以保存父级,并让其子级认为级联保存。如果在保存后重新查询父级并测试子级集合的大小,则看起来没问题。但实际上Hibernate并没有拯救孩子,而是缓存了父母,所以你正在看着未得救的孩子们。解决此问题的一种方法是清除保存和查询之间的会话缓存,以便您知道数据直接来自数据库。

这是ActiveRecord的问题吗?如果我保存模型然后在同一个测试中查询它,是否有可能我实际上并没有从数据库中获取数据,而是从查询缓存中获取数据?我还没有看到任何试图解决这个问题的样本测试,所以我想知道是否有什么东西可以解决这个问题?

2 个答案:

答案 0 :(得分:1)

是。根据您编写测试的方式,Rails查询缓存有时会产生干扰。有时rails很聪明,可以跟踪需要清除缓存的时间(当对象之间存在明显的关联时),但这里有一个不符合预期的示例:

user.posts.should == []
Post.create(:user_id => user.id)
user.posts.size.should_not == [] # Fails, since the original query was cached.

通常,如果在同一测试中执行两次相同的查询,则应在尝试执行第二个查询之前对数据调用.reload。像这样:

user.posts.should == []
Post.create(:user_id => user.id)
user.posts.reload
user.posts.size.should_not == []

根据我的个人经验,最好考虑一种不同的编写测试方法,而不是使用上述方法。例如,以下是编写上述内容的更好方法,不受查询缓存的影响:

lambda { Post.create(:user_id => user.id) }.should_change(user.posts, :count).by(1)

答案 1 :(得分:0)

我从未遇到过与ActiveRecord有关的问题。我的理解是缓存仅在读取时,因此总是执行保存。