Rails RSpec Tests for a has_many :through Relationship

I would recommend checking out a gem called Shoulda. It has a lot of macros for testing things like relationships and validations.

If all you want is to test that the has_many relationship exists, then you could do the following:

describe Post do
  it { should have_many(:categories) }
end

Or if you're testing a has_many :through, then you'd use this:

describe Post do
  it { should have_many(:categories).through(:other_model) }
end

I find the Shoulda Rdoc page very helpful too.


For the sake of completeness, in 2020 this is possible without additional gems.

  it "has many categories" do
    should respond_to(:categories)
  end

And even more explicit:

it "belongs to category" do
  t = Post.reflect_on_association(:category)
  expect(t.macro).to eq(:belongs_to)
end

(see Ruby API on Reflection)

The second example makes sure that a "has_one" is not confused with a "belongs_to" and vice versa

It is, however, not limited to has_many :through relationships, but can be used for any association applied to the model.

(Note: This is using the new rspec 2.11 syntax with Rails 5.2.4)


remarkable will do this nicely:

describe Pricing do

  should_have_many :accounts, :through => :account_pricings
  should_have_many :account_pricings
  should_have_many :job_profiles, :through => :job_profile_pricings
  should_have_many :job_profile_pricings

end

Generally, you just copy all of your relationships from the model to the spec and change "has" to "should_have", "belongs_to" to "should_belong_to", and so on. To answer the charge that it's testing rails, it checks the database also, making sure that the association works.

Macros are also included for checking validations as well:

should_validate_numericality_of :amount, :greater_than_or_equal_to => 0