Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check for a change from Nil in RSpec

Tags:

null

ruby

rspec

So I was pretty sure this was going to work...

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

but it fails with this message...

result should have initially been NilClass, but was NilClass

Hu?

First off, why does this return as a failure? Secondly, I know normally you can check for nil with be_nil by using the nil? method. Is there some special way to do this with a from().to() in RSpec?

like image 643
webdesserts Avatar asked Nov 30 '12 23:11

webdesserts


1 Answers

This should work:

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

rspec will use === to compare the value in from and to. But === is not commutative, and when called on a class it will check if its argument is an instance of the class. So:

NilClass === NilClass
#=> false

Because NilClass is not an instance of NilClass. On the other hand,

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

Because nil is an instance of NilClass, nil is equal to nil, but nil is not equal to NilClass.

You could also write your test in that way:

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

which I think is the most readable.

like image 99
Jean-Louis Giordano Avatar answered Oct 14 '22 23:10

Jean-Louis Giordano