Pitfalls of Rspec boolean matchers

Pitfalls of Rspec boolean matchers

Rspec provides a bunch of build-in matchers. They include matchers that help us work with boolean values. But not always these matchers are safe to use.

be_true and be_false matchers

I guess everybody used RSpec matchers be_true and be_false. There are a few examples with them:

but it’s good to know that the following expectations will also pass:

This happens because be_true and be_false matchers consider nil and false to be false and anything else to be true. To make tighter comparison and avoid potential issues use eql matcher:

Predicate matchers

Rspec provides predicate matchers for each ruby method which ends with ‘?’. For instance, we have a class with method empty? which returns true:

and Rspec file contains:

Everything works fine, but let’s do changes in our empty? method and return some object instead of Boolean:

and our test still passes even when we return something different from true. As be_true and be_false matchers, predicate matches consider nil and false to be false and anything else to be true.
To avoid potentials issues with this behaviour we also should make tighter comparison:

Summary

While testing boolean attributes or methods that return boolean value, try to avoid matchers described above.

UPD
Since RSpec 3 was released, this article is actual for RSpec 2