【发布时间】:2013-09-20 17:47:54
【问题描述】:
拥有庞大的模型堆栈并广泛使用玩偶缓存技术,最终会在模型更新后“触及”许多父模型。
在测试时,这似乎是在浪费时间,除非您尝试专门测试该功能。
有没有办法防止模型在测试环境或测试级别与touch 关联belongs_to?
更新 1:
我对这个案子的第一次尝试是
# /config/initializers/extensions.rb
#
class ActiveRecord::Base
def self.without_touch_for_association(association_name, &block)
association_name = association_name.to_sym
association = self.reflect_on_all_associations(:belongs_to).select { |reflection| reflection.name == association_name }.first
options = association.options
association.instance_variable_set :@options, options.except(:touch)
yield
association.instance_variable_set :@options, options
end
end
Post.without_touch_for_association(:user) do
Post.last.save
end
当然,没有成功,保存Post.last 还是会碰到User。
更新理由:
我理解并同意这种方法可能会导致错误,这根本不是一个好的做法。问题是我有一个包含大量集成和单元测试的巨大套件。娃娃缓存也深入模型树。每次查看日志时,我都会看到很大一部分与触摸相关的查询。我知道最好的方法是优化单元测试以添加更多的模拟和存根以及更少的持久性。在集成测试中解决问题更加困难。
无论如何,我问这个问题是为了学习和研究。我有兴趣探索这种技术的潜在速度改进。
解决方案:请参阅下面我自己的答案以获取工作代码。
【问题讨论】:
-
对于未提供直接解决方案提前致歉。但是,我首先会非常谨慎地尝试这样做,因为它会显着改变您的应用程序的行为,并成为纯生产错误的丰富潜在来源。如果
#touch调用确实导致您的测试套件显着变慢,那么似乎一开始就创建了太多的持久记录。您主要关心单元测试还是集成测试? -
感谢 SimonC!我用我的理由更新了这个问题。干杯!
-
好吧,我不认为这是一个很好的建议,但不能像这样的任何实例对 touch 方法进行存根:
User.any_instance.stub(:touch).and_return(true)所以它实际上并没有做任何事情?跨度> -
不。我指的是
belongs_to :user, touch: true,我想在其中使touch选项静音。
标签: ruby-on-rails rspec associations metaprogramming belongs-to