6

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

config.after(:each) do
  DatabaseCleaner.clean

  Currency.class_variable_set :@@default, nil
end
4

3 回答 3

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

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

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]

这样一切正常,如果您尝试将这些类的对象相互比较,则不会(不必要的)重新加载导致问题的类(请参阅我之前的评论)

于 2013-09-29T15:22:32.720 回答
4

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

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

请参阅:RSpec 类变量测试

于 2013-09-29T08:38:30.083 回答
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

这将在每次不同的测试之前运行您选择的内容。接受的解决方案至少没有解决我需要重置类变量的两种情况。

于 2014-09-12T02:15:40.763 回答