I'm upgrading to from Rails 4.2.6 to 5.0.0 and receiving undefined method
errors for all shoulda matchers. I'm using shoulda-matchers (3.1.1).
2) Location
Failure/Error: it { should validate_presence_of(:latitude) }
NoMethodError:
undefined method `validate_presence_of' for #<RSpec::ExampleGroups::Location:0x007ff81faa4de8>
# ./spec/models/location_spec.rb:6:in `block (2 levels) in <top (required)>'
# ./spec/rails_helper.rb:60:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:59:in `block (2 levels) in <top (required)>'
I managed to fix the error using the following. However,
this should be handled automatically by the gem:
RSpec.configure do |config|
config.include(Shoulda::Matchers::ActiveModel, type: :model)
config.include(Shoulda::Matchers::ActiveRecord, type: :model)
end
I'm having this problem with Rails 4.2.6. Explicitly including them solves it.
Could be due to the new way of configuring things in 3.X. I have a Rails 4.2.2 app using 2.8, no problem.
look, you can fix it with this link https://www.sitepoint.com/learn-the-first-best-practices-for-rails-and-rspec/
Try this:
Open your spec/rails_helper.rb file and configure shoulda-matchers to work with RSpec by pasting in the following:
require 'shoulda/matchers'
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
source: https://www.sitepoint.com/learn-the-first-best-practices-for-rails-and-rspec/
I'm seeing this as well after upgrading from 2.8.0 to 3.1.1, even when I configure RSpec with the aforementioned configs. The failing tests are all for Form Objects that include ActiveModel::Model. Any idea how to make those tests work?
Never mind. Just found the documentation: https://github.com/thoughtbot/shoulda-matchers#availability-of-matchers-in-various-example-groups
I'm closing this as I haven't been able to reproduce this in a Rails 5 app and everything works fine for me.
If anyone encounters this again, please see if you can reproduce this in a fresh Rails app and post a link to the repo so I can check it out. Thanks!
I am encountering this problem without adding the above proposed solution, since you wanted to see it. https://github.com/UpStage-Community/upstage-api. Check out the devise-auth branch, run bundle, run rspec, and validate_uniqueness_of will fail.
@rramsden's solution worked perfectly.
@creatyvtype How by chance are you running your tests? Are you using Spring to do so?
@mcmire just running "rspec". Nothin' fancy.
Although it is already closed, I came across this problem when I ran a spec for an ActiveModel::Model without define type: :model in Rspec.describe block.
The code bellow code fails with undefined_method error...
RSpec.describe NewInvestment do
context 'validations' do
it { is_expected.to validate_presence_of(:investment_product_id) }
end
end
...but this one works perfectly
RSpec.describe NewInvestment, type: :model do
context 'validations' do
it { is_expected.to validate_presence_of(:investment_product_id) }
end
end
I had the same issue using rails 4.2.5 and fixed it using the suggestion by @edsonlima
Just hit this issue on Ruby 2.4.2, Rails 5.1.4. gem 'shoulda-matchers', require: false and adding require 'shoulda/matchers' in spec/support/shoulda_matchers.rb solved it for me.
Install the gem shoulda-matchers
group :test do
gem 'shoulda-matchers'
end
Write following code in the rails_helper.rb
RSpec.configure do |config|
config.include(Shoulda::Matchers::ActiveModel, type: :model)
config.include(Shoulda::Matchers::ActiveRecord, type: :model)
end
@TorvaldsDB Are you using the Shoulda::Matchers.configure block as listed in the README? That should take care of incorporating the matchers into the proper example groups for you without having to do it explicitly.
Can confirm I ran into this issue today and was able to fix it with @rramsden changes.
I'm using rails 6-beta and it is still happening
@kaiomagalhaes What does your rails_helper.rb look like? Do you have Shoulda::Matchers.configure in this file or in a support file? Which version of shoulda-matchers are you using?
What about if I am using custom validator ?
class AccountValidator
include ActiveModel::Validations
attr_reader :name, :badge
validates :name, presence: true
validates :badge, presence: true, type: { type: :string }
def initialize(name, badge)
@name = name
@badge = badge
end
end
And the tests for it:
RSpec.describe AccountValidator do
subject { AccountValidator.new "Someone", "2324"}
it { should validate_presence_of(:name) }
it { should validate_presence_of(:badge) }
end
It always gives error:
undefined method `validate_presence_of' for #<RSpec::ExampleGroups::
Any suggestions ?
@clubbavi The gem relies on your example groups to be tagged. RSpec will do this automatically for specs that you've placed in spec/models, spec/controllers or spec/routing. If your test for AccountValidator is not located here then you will need to tag it accordingly:
RSpec.describe AccountValidator, type: :model do
# ...
end
This point is explained in the README but if there's something I need to make clearer, let me know. (EDIT: It occurs to me I don't have that _exact_ point in the README so I'll add another section.)
@mcmire , yes, it's not located inside those folders. It has a folder structure of app/validators.
I have tried with the above solution, but error is it cannot find the model.
As well as:
require 'shoulda-matchers'
RSpec.configure do |config|
config.include(Shoulda::Matchers::ActiveModel, type: :model)
config.include(Shoulda::Matchers::ActiveRecord, type: :model)
end
Still I couldn't go through.
Alright. What version of shoulda-matchers are you using? Do you have a Shoulda::Matchers.configure block in your rails_helper/spec_helper? What happens if you place the includes in your example group directly?
RSpec.describe AccountValidator do
include Shoulda::Matchers::ActiveModel
include Shoulda::Matchers::ActiveRecord
end
@mcmire ... we are using 4.0.0.rc1.
By adding the above code I am getting an error:
Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeDoesNotExistError:
The matcher attempted to set :name on the AccountValidator to nil,
but that attribute does not exist.
RSpec.describe AccountValidator do
include Shoulda::Matchers::ActiveModel
include Shoulda::Matchers::ActiveRecord
subject { AccountValidator.new "Someone", "2324"}
it { should validate_presence_of(:name) }
it { should validate_presence_of(:badge) }
end
@clubbavi You can switch to 4.0.0 now, it's been released :) But okay. What does your validator class look like?
@mcmire ... I will try with the latest version.
My validator class:
class AccountValidator
include ActiveModel::Validations
attr_reader :name, :badge
validates :name, presence: true
validates :badge, presence: true, type: { type: :string }
def initialize(name, badge)
@name = name
@badge = badge
end
end
I can write the rspec for initializers. But not sure of validates.
@mcmire , I just tested with the recent version. Still the same issue.
For
it { should validate_presence_of(:name) }
Gives error:
Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeDoesNotExistError:
The matcher attempted to set :name on the AccountValidator to
nil, but that attribute does not exist.
I have added in the configuration:
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :active_record
with.library :active_model
end
end
& in the _sepc file:
RSpec.describe AccountValidator, type: :model do
...
end
@clubbavi So it looks like your Validator class does not have attr_writers for the attributes. That is why it's telling you that the attribute doesn't exist. This is what I was saying before 鈥斅爐his is not how the model matchers are designed to be used. If your class looked like this:
class AccountValidator
include ActiveModel::Validations
attr_accessor :name, :badge
validates :name, presence: true
validates :badge, presence: true, type: { type: :string }
end
then validate_presence_of and friends would work. (At that point though, I would argue you don't have a validator, but a model.)
Had the same issue, got it working by adding
RSpec.configure do |config|
config.include(Shoulda::Matchers::ActiveModel, type: :model)
config.include(Shoulda::Matchers::ActiveRecord, type: :model)
end
as mentioned by most of the people in this thread
shoulda-matchers-4.1.2
ruby 2.5.3
rails - 5.2.3
In my case someone added rails_helper.rb to the project with Shoulda::Matchers configuration, but that helper wasn't required in any test file, so the method wasn't found.
I ended up just adding the Shoulda::Matchers config to spec_helper.rb, though in general it's recommended to have separate rails_helper and spec_helper. https://github.com/everydayrails/rails-4-1-rspec-3-0/issues/36#issuecomment-68499694
Most helpful comment
Try this:
Open your spec/rails_helper.rb file and configure shoulda-matchers to work with RSpec by pasting in the following:
require 'shoulda/matchers'
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
source: https://www.sitepoint.com/learn-the-first-best-practices-for-rails-and-rspec/