2012-11-30 8 views
10

quindi ero abbastanza sicuro che questo stava andando al lavoro ...Come controllare per un cambiamento da zero nel RSpec

expect { file.send(:on_io) {} }.to change{ 
    file.io.class 
}.from(NilClass).to(File) 

ma non riesce con questo messaggio ...

result should have initially been NilClass, but was NilClass 

Hu?

Prima di tutto, perché questo restituisce un errore? In secondo luogo, so che normalmente è possibile verificare la presenza di zero con be_nil utilizzando il metodo nil?. C'è un modo speciale per farlo con uno from().to() in RSpec?

risposta

11

Questo dovrebbe funzionare:

expect { file.send(:on_io) {} }.to change{ 
    file.io 
}.from(NilClass).to(File) 

rspec utilizzerà === per confrontare il valore di from e to. Ma === non è commutativo e quando viene chiamato su una classe controllerà se il suo argomento è un'istanza della classe. Quindi:

NilClass === NilClass 
#=> false 

Perché NilClass non è un'istanza di NilClass. D'altra parte,

NilClass === nil 
#=> true 
nil === nil 
#=> true 
nil === NilClass 
#=> false 

Poiché nil è un'istanza di NilClass, zero è uguale a zero, ma nil non è uguale a NilClass.

Si potrebbe anche scrivere il test in questo modo:

expect { file.send(:on_io) {} }.to change{ 
    file.io 
}.from(nil).to(File) 

che credo sia il più leggibile.

+0

se 'nil === NilClass' restituisce false, non' file.io === File' restituisce anche false (supponendo che 'file.io' sia un'istanza di' File')? – webdesserts

+1

Ma il test sarà 'File === file.io', questo è il punto intero :) –

+1

Ahh ok, gli argomenti in' to' e 'from' vengono confrontati con il valore restituito piuttosto che con il visto. Ha senso. Grazie a te che hai spiegato tutto bene! – webdesserts

Problemi correlati