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.

+3


source to share


2 answers


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.

+1


source


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.

0


source







All Articles