Ответ 1
describe DataFactory
before(:each) { DataFactory.class_variable_set :@@url, nil }
...
end
У меня есть следующий класс: Я хочу, чтобы 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
У меня есть два теста:
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
Проблема заключается в том, что второй тест никогда не генерирует исключение, поскольку переменная класса @@url по-прежнему устанавливается из первого теста, когда выполняется второй тест. Несмотря на то, что у меня есть экземпляр для nil в конце первого теста, сбор мусора не очистил память до того, как пройдет второй тест:
Любые идеи были бы замечательными! Я слышал, что вы могли бы использовать Class.new, но я не уверен, как это сделать.
describe DataFactory
before(:each) { DataFactory.class_variable_set :@@url, nil }
...
end
Вот альтернатива принятому ответу, которая, хотя и не решит ваш конкретный пример, я надеюсь, что это может помочь нескольким людям с вопросом в том же духе. Если класс, о котором идет речь, не указывает значение по умолчанию и остается undefined до установленного значения, это работает:
describe DataFactory
before(:each) do
DataFactory.remove_class_variable :@@url if DataFactory.class_variable_defined? :@@url
end
...
end
Работает для меня с классом с чем-то более похожим:
def initialize
@@url ||= MY_CONFIG["my value"]
...
end