RSpec matchers combinators

1 minute read

Rspec matchers are a lot like predicates. Predicates that can talk … The good thing about predicates, as anybody who has done a bit of functional programming will tell you, is that they are easy to combine together into bigger predicates. I was really suprised to see that rspec does not come with such simple combinators as ‘and’ or ‘or’.

Here is a gist where I define simple combinators :

With this and the email_spec matchers, it is possible to write something like this to find if an email was sent by rails :

expect(all_emails).to have_any_that(and_(deliver_to(receiver),
                                         have_subject(subject),
                                         have_body_text(body)))

It enables expressive test code and high reusability.

Using the ‘all’ combinator it is possible to write things like that :

expect(sample_items_attributes).to all_ have_key(:price)

I had to prepend ‘all’ and ‘and’ with an underscore because I would otherwise get conflicts… I’m not overly satisfied with this, but it will do for the moment.

I was happily supprised by the readability of error messages when the mach fails. Rspec does a very good job about this. I think it would be possible to get even better error messages by explicity using the sub matchers messages though. If anyone is interested, help yourself !

I usually write about 15 minutes worth of reading per month. I won't transfer your email. No Spam, unsubscribe whenever you want.

As a gift for subscribing, you'll receive an illustrated mini-ebook "How to start a team coding dojo"!

Leave a comment