如何禁用belongs_to的:触摸选项Rspec的测试Rails的模式? [英] How to disable belongs_to :touch option in Rspec tests for Rails models?
问题描述
有一个大模型堆栈和利用娃娃缓存技术广泛,人们有很多家长模型的模型更新后,被感动结束。
Having a large model stack and using doll caching techniques extensively, one ends up with lots of parent models been "touched" after a model update.
测试时,这似乎是一个浪费时间,除非你试图专门测试功能。
While testing, this seems to be a time waster unless you try to test that feature specifically.
有没有办法来prevent车型触摸
测试环境,或在其 belongs_to的
协会测试水平?
Is there a way to prevent models to touch
their belongs_to
associations for the test environment or at a test level?
更新1:
我的第一次尝试的情况下将
My first attempt to the case would be to
# /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
还是触动它的用户
。
UPDATING理由:
UPDATING RATIONALE:
我理解并同意,这种做法可能是错误的根源,这不是一个很好的做法都没有。事情是,我有一个巨大的套房,有很多都集成和单元测试。娃娃缓存也得到在模型树很深。我每次看日志,我看到触摸相关查询的显著%。我所知道的最好的办法就是优化了单元测试,以增加更多的嘲弄和存根和更少的持久性。集成测试中解决的问题是比较困难。
I understand and agree that this approach may be a source of bugs and it's not a good practice at all. The thing is that I have a huge suite with lots of both integration and unit tests. Doll caching also gets deep in the model tree. Every time I look at the logs, I see a significant % of touch-related queries. I know the best way would be optimizing the unit tests to add more mocking and stubbing and less persistence. Solving the issue within integration tests is more difficult.
在任何情况下,我所要求的学习和研究的缘故这个问题。我感兴趣的是探索这一技术的潜在速度的改进。
In any case, I'm asking this question for the sake of learning and research. I am interested in exploring the potential speed improvements of this technique.
解决方法:请参阅下面的工作code我自己的答案
SOLUTION: see my own answer below for the working code.
推荐答案
钢轨> = 4.2
由于@Dorian,在Rails的4.2去使用 ActiveRecord的方式: :NoTouching
Thanks to @Dorian, in Rails 4.2 the way to go is using ActiveRecord::NoTouching.
钢轨< 4.2
我的工作code在RSpec的支持文件:
My working code in rspec support file:
# /spec/support/active_record_extensions.rb
class ActiveRecord::Base
def self.without_touch_for_association(association, &block)
method_name = :"belongs_to_touch_after_save_or_destroy_for_#{association}"
return unless self.instance_methods.include?(method_name)
method = self.send(:instance_method, method_name)
self.send(:define_method, method_name) { true }
yield
self.send(:define_method, method_name, method)
nil
end
def self.disable_touch_associations!
associations = self.reflect_on_all_associations(:belongs_to)
associations.each do |association|
self.without_touch_for_association association.name do
return
end
end
nil
end
end
添加到您的 ./规格/ spec_helper.rb
来禁用任何模型全触摸通话定义,整个测试套件:
Add this to your ./spec/spec_helper.rb
to disable all touch calls for any model defined, for the whole test suite:
RSpec.configure do |config|
if ENV['SILENCE_TOUCHES']
config.before :suite do
ActiveRecord::Base.descendants.each {|model| model.disable_touch_associations! }
end
end
end
Temporarely禁止在特定的测试模型和联想触摸。
Temporarely disabling a touch for a model and association in a particular test.
Post.without_touch_for_association(:user) do
Post.last.save
end
由于以下@xlembouras指着我正确的方向!
Thanks to @xlembouras below for pointing me to the right direction!
我在玩我们的测试这个功能,我注意到在测试套件速度降低25%,对于一个30分钟的测试套件。我可能会更深入的研究后,发布更准确的结果。
I'm playing with this feature on our tests and I'm noticing a 25% reduction in test suite speed, for a 30min test suite. I may post more accurate results after more thorough research.
这篇关于如何禁用belongs_to的:触摸选项Rspec的测试Rails的模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!