Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shoulda matchers have_many with custom relation name

How do I test this ActiveRecord relation using shoulda matchers?

Models

class User < ActiveRecord::Base
  has_many :articles
end

class Article < ActiveRecord::Base
  belongs_to :author, class_name: 'User'
end

Test

describe User do
  it { should have_many(:articles) }
end

I'm getting the following error:

1) User should have many articles
     Failure/Error: it { should have_many(:articles) }
       Expected User to have a has_many association called articles (Article does not have a user_id foreign key.)
     # ./spec/models/user_spec.rb:4:in `block (2 levels) in <top (required)>'

So it obviously expects relation field to be named user_id because of User class name. I expect there has to be some test method that can be used to override this expectation like

it { should have_many(:articles).as(:owner) }

But I can't find anything like it. Am I missing something obvious?

like image 516
Igor Pantović Avatar asked Feb 09 '14 10:02

Igor Pantović


People also ask

How do I use matchers in one-liner form?

As the name of the gem indicates, most matchers are designed to be used in "one-liner" form using the should macro, a special directive available in both RSpec and Shoulda. For instance, a model test case may look something like:

Why should I use Shoulda matchers?

In order to have as few dependencies as possible, all of shoulda’s built-in matchers are written as concrete classes and methods. Another thing that should be said is that, although matchers tend to use more lines than an equivalent assertion or macro, they’re frequently less terse, so they can be easier to read and write despite their length.

Are matchers easier to test?

Because the matcher doesn’t generate a test, you can write your own test name if you’d like Matchers are easier to test, because they’re just Ruby objects One thing you’ll immediately notice is that the matcher for this example is undeniably longer.

What is the difference between the belong_to matcher and define_ENUM_for matcher?

The belong_to matcher is used to ensure that a belong_to association exists on your model. The define_enum_for matcher is used to test that the enum macro has been used to decorate an attribute with enum methods.


1 Answers

shoulda matchers includes a .with_foreign_key() option.

https://github.com/thoughtbot/shoulda-matchers#have_many

So in your example:

describe User do
  it { should have_many(:articles).with_foreign_key('author_id') }
end

Which is how your model should, I believe:

class User < ActiveRecord::Base
  has_many :articles, foreign_key: "author_id"
end
like image 161
veritas1 Avatar answered Dec 01 '22 20:12

veritas1