Shoulda-matchers: Add documentation for change in how matchers are mixed in

Created on 13 Oct 2015  路  8Comments  路  Source: thoughtbot/shoulda-matchers

Add a new "Getting Started" guide that goes into more detail about this.

Refs #797.

UX

Most helpful comment

The association matchers, as well as the accept_nested_attributes_for matcher, are Active_Record_ matchers, not Active_Model_ ones.

They should get mixed in automatically when you use type: :model. If that doesn't work for some reason, then add this to your example group:

include Shoulda::Matchers::ActiveRecord

(you shouldn't need to extend the example group, the matchers don't need to be available as class methods)

All 8 comments

+1

I've just reached this page as I was trying to use shoulda-matchers in shared examples in a rails engine gem that I'm working on. It wasn't working without having specified type: :model.

@mcmire in https://github.com/thoughtbot/shoulda-matchers/issues/797, you said:

In 3.0, matchers are now mixed into specific example groups tagged with :model, :controller, or :routing. If your example group isn't tagged with this or isn't in any of the standard locations, then you'll need to mix a module into your example group, in this case the Shoulda::Matchers::ActiveModel module.

However, it didn't work for me when I added:

include Shoulda::Matchers::ActiveModel
extend Shoulda::Matchers::ActiveModel

Did you think of some other way of mixing in the matchers?

@vfonic Which matchers are you trying to use?

The one that was failing was have_one matcher:

it { is_expected.to have_one(:profile).dependent(:destroy) }

Error:

expected #<User:0x007fee9637ab68> to respond to `has_one?`

The ones that are failing now (if I remove type: :model):

dependent # I've added dependent(:destroy) later, the error before was the one above
delegate_method # weirdly, this one isn't failing

Here are the full errors now:

Failure/Error: it { is_expected.to accept_nested_attributes_for(:profile) }
     NoMethodError:
       undefined method `accept_nested_attributes_for' for #<RSpec::ExampleGroups::Profile::BehavesLikeActsAsProfile::Validations:0x007fa373b76bc8>
     Shared Example Group: "acts_as_profile" called from ./spec/models/concerns/acts_as_profile_spec.rb:17
     # ./spec/shared/acts_as_profile.rb:11:in `block (3 levels) in <module:Profile>'

     Failure/Error: .dependent(:destroy)
     NoMethodError:
       undefined method `dependent' for #<RSpec::Matchers::BuiltIn::Has:0x007fa37710f960>

I've changed the class names to dummy ones, but I hope it's still understandable.

The association matchers, as well as the accept_nested_attributes_for matcher, are Active_Record_ matchers, not Active_Model_ ones.

They should get mixed in automatically when you use type: :model. If that doesn't work for some reason, then add this to your example group:

include Shoulda::Matchers::ActiveRecord

(you shouldn't need to extend the example group, the matchers don't need to be available as class methods)

That works! Thanks @mcmire!

type: :model works, but I prefer having the matchers included in shared examples, just in case if someone forgets to add type: :model, so that his tests don't fail.

This makes it very challenging to test if you're not loading Rails. :(

I ended up adding another section to the README about this, so this issue isn't as important. I still think a Getting Started guide would be nice so we can add more words without cluttering up the README.

I forgot what my plans were for this, but I think this is now covered in this section, so I'm closing this: https://github.com/thoughtbot/shoulda-matchers#availability-of-matchers-in-various-example-groups

Was this page helpful?
0 / 5 - 0 ratings