Be false vs be_falsey in rspec
I know that false will just return true if the expected value is purely false, wherease be_falsey will return true if the expected value is false or nil.
However, I don't understand when I will use one or the other. I don't see an example where be_falsey would be more useful than false.
source to share
There are many situations in Ruby where you get a result nil
and want to treat it like false
. For example, suppose we have a method that processes hash parameters and we want the absence of an option to be the same as an option set to false:
def verbose?(opts)
opts[:verbose]
end
opts = { verbose: false }
expect(verbose?(opts)).to be_falsey # => PASS
opts = { verbose: true }
expect(verbose?(opts)).to be_falsey # => FAIL
opts = {}
expect(verbose?(opts)).to be_falsey # => PASS
Obviously this is a simplified example (you could argue that you verbose?
should always return true
or false
), but similar scenarios are common in Ruby.
source to share
One example I can think of is unit test method for method. The method will be used in such a way that you are not interested in the result, but only if it is true / false.
Consider a method that checks if there is an entry with a given value located in db:
Class Foo
def self.has_value? value
Foo.find(value: value)
end
This method will be used like:
if Foo.has_value?(value)
...
Now you can write your test like this:
let(:foo ){ create :foo )
expect(Foo.has_value?(1)).to == foo
But this hides the intent of the method. The purpose of the method is not to find foo. It should tell you if foo exists with the given value.
To express the intent of a method, it would be better to use
expect(Foo.has_value(1).to be_truthy
expect(Foo.has_value(2).to be_falsey
Rails often uses if model.save
. This is the same pattern.
source to share