用于在rspec测试之间重置类变量的清洁解决方案

时间:2013-09-29 08:21:51

标签: ruby-on-rails rspec rspec-rails

是否有更好的方法在Rspec测试之间清除类变量,而不是从after(:each)方法中明确地清除它们?我更喜欢一种“清除所有”的方式,而不必记得每次都将它们添加到config.after ...

config.after(:each) do
  DatabaseCleaner.clean

  Currency.class_variable_set :@@default, nil
end

3 个答案:

答案 0 :(得分:6)

我最终通过在lib / auto_clean_class_variables.rb中定义一个方法来重置给定类的所有类变量

module AutoCleanClassVariables
  def reset_class_variables
    self::CLASS_VARIABLES_TO_CLEAN.each do |var|
      class_variable_set var, nil
    end
  end
end

从config.after(:each)中调用此方法,位于spec_helper.rb

config.append_after(:each) do
  DatabaseCleaner.clean

  # Find all ActiveRecord classes having :reset_class_variables defined
  classes = ActiveSupport::DescendantsTracker.descendants(ActiveRecord::Base)
  classes.each do |cl|
    if cl.methods.include?(:reset_class_variables)
      cl.reset_class_variables
    end
  end
end

需要“清理”的模型可以引导此行为:

extend AutoCleanClassVariables
CLASS_VARIABLES_TO_CLEAN = [:@@default]

这样一切正常,如果你试图将这些类的对象相互比较,那么没有(不必要的)重新加载类导致问题(参见我之前的评论)

答案 1 :(得分:4)

您应该能够在每次运行后重新加载该类:

after(:each) do
  Object.send(:remove_const, 'Currency')
  load 'currency.rb'
end

请参阅:RSpec Class Variable Testing

答案 2 :(得分:1)

在spec_helper.rb中包含此内容

Spec::Runner.configure do |config|
  config.before(:all) {}
  config.before(:each) {
       Class.class_variable_set :@@variable, value
  }
  config.after(:all) {}
  config.after(:each) {}
end

这将在每次不同测试之前运行您选择的内容。已接受的解决方案至少解决了我需要一个类变量重置的2个案例。