How to implement have_many/belong_to RSpec matchers

You’re going to writing test for you’re ActiveRecord models to check if they have a specific set of associations?!

You have two options; going with shoulda-matchers gem (that’s a great gem, though) or writing a simple version of yourself for learning or reduce complexity of using too many gems.

At first you should create a file under spec/support/ called association.rb (call it whatever you want) then require it in your test helper (whether it’s spec_helper or rails_helper)

require_relative "support/association"

And all you have to do is


Here we have defined two matchers have_many and belong_to using ActiveRecord::Reflection#reflect_on_association which allows us to get a AssociationReflection object to check whether an association with a specific named is declared or not. Actually to avoid complexity I’ve skipped error handling part which you can steal from shoulda-matchers gem to be more concise.

NOTE: I’ve used duplication to avoid Ruby magic (meta-programing or clever solution) and I’ve called reflect_on_association twice one for it { should ... } blocks which passes a instance of expected class instead of class itself so we should call reflect_on_association on parent class using .class and the other is for normal it "...." { expected(klass).to have_many(:books) } blocks which reflect_on_association would be called directly on class itself.

And now you can write test cases like this:


That’s it, hope you’ve enjoyed. It’s good to go under the hood and get dirty to see how Ruby/Ruby On Rails magic works.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store