Reputation: 16809
I'm using RSpec to test an API. I want to specify that one particular endpoint returns a boolean value, either true
or false
. This is an API to be used by other systems and languages, and so it's important for it to be an actual boolean, not merely something that Ruby will evaluate to false
or true
.
But I don't see a way to do this because there's no Boolean
type in Ruby.
Upvotes: 32
Views: 26459
Reputation: 2275
It's a long time later, but here's what I settled on:
foo.should satisfy {|x| [true, false].map(&:object_id).include? x.object_id}
This works because true and false only have one instance. Also, more of a curiosity, but they also always have the same instance id.
Upvotes: 2
Reputation: 38428
I had the same problem. This is what I came up with:
RSpec::Matchers.define :be_boolean do
match do |actual|
expect(actual).to be_in([true, false])
end
end
See: https://www.relishapp.com/rspec/rspec-expectations/v/3-4/docs/custom-matchers
It can be used like so:
it 'is boolean' do
expect(true).to be_boolean
end
Upvotes: 26
Reputation: 10054
In more recent rspec versions one can use compound matchers:
expect(thing).to be(true).or be(false)
Upvotes: 22
Reputation: 858
How about a combination of the above?
RSpec::Matchers.define :be_boolean do
match do |value|
[true, false].include? value
end
end
usage:
expect(something).to be_boolean
Upvotes: 9
Reputation: 470
Add the gem rspec_boolean to your Gemfile in the group :development, :test:
gem 'rspec_boolean'
And than use it like:
expect(val.is_done).to be_boolean
Upvotes: 1
Reputation: 4293
While Ruby doesn't have a Boolean
class, it does have TrueClass and FalseClass, of which true
and false
are the only instances. I'm sure you could test against either of those two and be good to go.
true.is_a? TrueClass # => true
(1 == 1).is_a? TrueClass # => true
1.is_a? TrueClass # => false
false.is_a? FalseClass # => true
(1 == 2).is_a? FalseClass # => true
nil.is_a? FalseClass # => false
Upvotes: 2