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

发布于 2024-08-22 18:12:31 字数 345 浏览 2 评论 0原文

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

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

In the Hibernate world, you can often have unit tests that appear to pass but there are actually bugs that don't show up because you're dealing with cached data. For example, you may save a parent with its children thinking it's cascading the save. If you re-query for the parent after the save and test the size of the child collection, it looks ok. But in reality Hibernate didn't save the children but cached the parent so you're looking at the un-saved children. One way to get around this is to clear the session cache between the save and the query so you know the data is coming straight from the database.

Is this an issue with ActiveRecord? If I save a model and then query it in the same test, is it possible that I'm not actually getting the data from the database but rather from the query cache? I haven't seen any sample tests that try to deal with this so I'm wondering if there's something that makes it a non-issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷弦 2024-08-29 18:12:31

是的。根据您编写测试的方式,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)

Yes. Depending on how you write your tests the Rails query cache can sometimes interfere. Sometimes rails is smart enough to keep track of when the cache needs to be cleared (When there is an obvious association between objects), but here is an example that would not behave as expected:

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

In general, if you are executing the same query twice in the same test you should call .reload on the data prior to attempting to executing the second query. Like so:

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

In my personal experience it is better to consider a different way of writing the test than to use the method above. For example, here's a better way of writing the above that will not be affected by the query cache:

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

梦途 2024-08-29 18:12:31

我从来没有遇到过 ActiveRecord 的问题。我的理解是缓存仅用于读取,因此始终执行保存。

I have never run into this as an issue with ActiveRecord. My understanding is that the cache is only on reads, so saves are always performed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文