2011-11-25 11 views
15

Ho la seguente classe: Voglio garantire che l'url della classe sia impostato una sola volta per tutte le istanze.Come cancellare le variabili di classe tra i test rspec in ruby ​​

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 

ho due prove:

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 

Il problema è la seconda prova non genera un'eccezione come variabile @@ classe URL è ancora impostato dal primo test quando il secondo test. Anche se l'istanza è stata annullata alla fine del primo test, la garbage collection non ha cancellato la memoria prima dell'esecuzione del secondo test:

Qualsiasi idea sarebbe ottima! Ho sentito che potresti usare Class.new ma non sono sicuro su come procedere.

+0

esattamente relativo al tuo problema, ma: * mai * usa le variabili di classe @@ in Ruby. Utilizza invece le variabili di istanza @class. Si comportano in modo molto più prevedibile. –

risposta

19
describe DataFactory 
    before(:each) { DataFactory.class_variable_set :@@url, nil } 
    ... 
end 
+1

Quando ho eseguito questo ho ottenuto il seguente errore: ** NameError: variabile di classe non inizializzata @@ url in oggetto ** ho preso a lavorare con: 'prima (: ciascuno) fare DataFactory.class_eval {class_variable_set: @@ url, nil} end' _Io sto usando JRuby 1.6.5 che credo utilizzi Ruby 1.8.9 e class_variable_set potrebbe essere privato in questa versione quindi ho dovuto usare class_eval_ Vedere: [http: //www.khelll .com/blog/ruby ​​/ ruby-riflessione-2 /] –

3

Ecco un'alternativa alla risposta accettata, che pur non risolverebbe il tuo esempio particolare, spero che potrebbe aiutare alcune persone con una domanda nella stessa vena. Se la classe in questione non specifica un valore di default, e rimane indefinita fino al set, questo sembra funzionare:

describe DataFactory 
    before(:each) do 
    DataFactory.remove_class_variable :@@url if DataFactory.class_variable_defined? :@@url 
    end 
    ... 
end 

Opere per me con una classe con qualcosa di più simile:

def initialize 
    @@url ||= MY_CONFIG["my value"] 
    ... 
end 
Non
Problemi correlati