【问题标题】:Is it important to deal with query caching in ActiveRecord unit tests?在 ActiveRecord 单元测试中处理查询缓存是否重要?
【发布时间】:2010-02-23 03:03:08
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案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)

    【讨论】:

      【解决方案2】:

      我从来没有遇到过 ActiveRecord 的问题。我的理解是缓存只在读取时,所以总是执行保存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        • 2011-05-06
        • 1970-01-01
        • 2010-11-28
        • 2021-11-17
        相关资源
        最近更新 更多