如何在ruby中清除rspec测试之间的类变量

Kev*_*ite 21 ruby variables rspec class

我有以下类:我想确保类url仅为所有实例设置一次.

class DataFactory
  @@url = nil

  def initialize()
begin
    if @@url.nil?
       Rails.logger.debug "Setting url"
       @@url = MY_CONFIG["my value"]
    end
rescue Exception
  raise DataFactoryError, "Error!"
end
  end
end
Run Code Online (Sandbox Code Playgroud)

我有两个测试:

it "should log a message" do
  APP_CONFIG = {"my value" => "test"}
  Rails.stub(:logger).and_return(logger_mock)
  logger_mock.should_receive(:debug).with "Setting url"

  t = DataFactory.new
  t = nil
end

it "should throw an exception" do
  APP_CONFIG = nil

  expect {
    DataFactory.new
  }.to raise_error(DataFactoryError, /Error!/)
end
Run Code Online (Sandbox Code Playgroud)

问题是第二个测试从不抛出异常,因为@@ url类变量仍然是在第二个测试运行时从第一个测试设置的.即使我在第一次测试结束时将实例设置为nil,但在第二次测试运行之前,垃圾收集还没有清除内存:

任何想法都会很棒!我听说你可能会使用Class.new,但我不知道该怎么做.

Mor*_*ori 22

describe DataFactory
  before(:each) { DataFactory.class_variable_set :@@url, nil }
  ...
end
Run Code Online (Sandbox Code Playgroud)

  • 当我运行这个时,我收到以下错误:**NameError:未初始化的类变量@@ url in Object**我使用它来执行:`before(:each)do DataFactory.class_eval {class_variable_set:@@ url,nil}结束`_我正在使用JRuby 1.6.5,我相信使用Ruby 1.8.9并且class_variable_set在这个版本中可能是私有的,所以我不得不使用class_eval_参见:[http://www.khelll.com/blog/ruby/ruby-反射-2 /] (2认同)

jle*_*enz 5

这是已接受答案的替代方法,虽然不能解决您的特定示例,但我希望它可以帮助一些人以同样的方式提出问题。如果所讨论的类未指定默认值,并且在设置之前一直未定义,则这似乎可行:

describe DataFactory
  before(:each) do
    DataFactory.remove_class_variable :@@url if DataFactory.class_variable_defined? :@@url
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)

为我工作的班级更像是:

def initialize
  @@url ||= MY_CONFIG["my value"]
  ...
end
Run Code Online (Sandbox Code Playgroud)