I noticed following line
expect(actual).to be_invalid
while I was looking at https://github.com/perfectline/validates_url/blob/81ec1516423af0b4fdc7cabbcda0089e434f2703/lib/validate_url/rspec_matcher.rb#L5
I tried to look for that matcher's implementation in rspec-core, rspec-expectations and rspec-rails gems but I could find only be_valid
and that too only in rspec-rails https://rubydoc.info/gems/rspec-rails/RSpec%2FRails%2FMatchers:be_valid
which made me wonder how does be_invalid
is made available because when I used that matcher in a test example it didn't raised any not defined method error.
Can anybody please help in making me understand how does that work?
Thanks.
A method that ends in a question mark is called a predicate. They look like this:
RSpec has a pretty cool predicate matcher that looks like this:
It works by using
method missing
to select theBePredicate
matcher. The matcher works by stripping off thebe_
with a regex and appending a?
, thensend
ing that method to the subject of the expectation.be_valid
andbe_invalid
are no different. Bothvalid?
andinvalid?
are defined on ActiveModel::Validations.So, if you're doing this:
RSpec is using its predicate matcher to call
User.new.invalid?
and return the result. Same goes forbe_valid
. Unless, that is, you're usingRSpec::Rails
, which contains aBeValid
matcher that overrides RSpec's predicate matcher so that it can print out all the validation errors when the spec fails.