Skip to Content

Rspec - Predicate matchers

Posted on

Ruby objects commonly provide predicate methods:

7.zero?                  # => false
0.zero?                  # => true
[1].empty?               # => false
[].empty?                # => true
{a: 5}.has_key?(:b)      # => false
{b: 5}.has_key?(:b)      # => true

You can test this all methods by using:

expect(7.zero?).to eq true # fails with "expected true, got false (using ==)"

but Rspec provides dynamic predicate matchers that are more readable and provide better failure output.

expect(7).not_to be_zero       # calls 7.zero?
expect([]).to be_empty         # calls [].empty?
expect(x).to be_multiple_of(3) # calls x.multiple_of?(3)
expect(hash).to have_key(:foo)       # calls hash.has_key?(:foo)
expect(array).not_to have_odd_values # calls array.has_odd_values?

It could be use for custom method (public/private), which return true/false:

class TestClass
  def has_secret?
    true
  end
end

RSpec.describe 'test class' do
  subject { TestClass.new }

  # deliberate failure
  it { is_expected.to have_secret }
end

Reference

comments powered by Disqus