How do I test this ActiveRecord relation using shoulda matchers?
class User < ActiveRecord::Base
has_many :articles
end
class Article < ActiveRecord::Base
belongs_to :author, class_name: 'User'
end
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?
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:
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With